Class: DiscordStore::GuildLimits
- Inherits:
-
Object
- Object
- DiscordStore::GuildLimits
- Defined in:
- lib/discord_store/guild_limits.rb
Overview
Discovers how large an attachment this guild will actually accept.
Every previous library in this genre hardcoded the number, and every one of them broke, because Discord has moved it repeatedly and in both directions: 8 MiB for years, then 25 MB, then back to 10 MB, with boosted guilds on a different ladder again. Published write-ups from 2023 and 2026 disagree, and both were right when they were written.
So the number is treated as a fact about the running system rather than a constant. The tier table below is a conservative starting point; #probe! measures the truth by trying.
Constant Summary collapse
- MIB =
1024 * 1024
- TIER_LIMITS =
Deliberately pessimistic. Being wrong low costs a few extra chunks; being wrong high costs a failed upload halfway through a large file.
{ 0 => 10 * MIB, 1 => 10 * MIB, 2 => 50 * MIB, 3 => 100 * MIB }.freeze
- FALLBACK_LIMIT =
8 * MIB
- REQUEST_OVERHEAD =
Room for multipart framing, the payload_json part, and headers, so that a chunk sized at exactly the ceiling does not push the request over it.
16 * 1024
Instance Method Summary collapse
-
#attachment_limit(refresh: false) ⇒ Integer
Largest attachment this guild accepts, in bytes.
-
#chunk_size ⇒ Integer
Bytes per blob chunk: the attachment ceiling less request overhead, unless the caller pinned it in configuration.
-
#initialize(rest:, config:) ⇒ GuildLimits
constructor
A new instance of GuildLimits.
-
#probe!(channel_id:, low: MIB, high: 100 * MIB, precision: MIB / 4) ⇒ Integer
Measures the real ceiling by binary search, uploading and then deleting throwaway attachments.
Constructor Details
#initialize(rest:, config:) ⇒ GuildLimits
Returns a new instance of GuildLimits.
33 34 35 36 37 |
# File 'lib/discord_store/guild_limits.rb', line 33 def initialize(rest:, config:) @rest = rest @config = config @mutex = Mutex.new end |
Instance Method Details
#attachment_limit(refresh: false) ⇒ Integer
Largest attachment this guild accepts, in bytes.
43 44 45 46 47 48 |
# File 'lib/discord_store/guild_limits.rb', line 43 def (refresh: false) @mutex.synchronize do @attachment_limit = nil if refresh @attachment_limit ||= discover_limit end end |
#chunk_size ⇒ Integer
Bytes per blob chunk: the attachment ceiling less request overhead, unless the caller pinned it in configuration.
54 55 56 |
# File 'lib/discord_store/guild_limits.rb', line 54 def chunk_size @config.chunk_size || ( - REQUEST_OVERHEAD) end |
#probe!(channel_id:, low: MIB, high: 100 * MIB, precision: MIB / 4) ⇒ Integer
Measures the real ceiling by binary search, uploading and then deleting throwaway attachments.
Costs a handful of requests and writes garbage into the channel briefly, so it is opt-in. Run it once at deploy time and pin the result in configuration rather than probing on every boot.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/discord_store/guild_limits.rb', line 70 def probe!(channel_id:, low: MIB, high: 100 * MIB, precision: MIB / 4) raise ArgumentError, "low must be under high" unless low < high best = nil while high - low > precision midpoint = low + ((high - low) / 2) if upload_succeeds?(channel_id, midpoint) best = midpoint low = midpoint else high = midpoint end end best ||= low @mutex.synchronize { @attachment_limit = best } best end |