Wednesday, July 15, 2026 2:56:53 AM
> delivery_overseer.rb
# frozen_string_literal: true

module ESM
  module Discord
    class Bot
      #
      # The single chokepoint for every outbound Discord message. Source threads (command replies, log events, XM8
      # notifications, ...) enqueue here and a small pool of workers performs the actual sends, pausing +check_every+
      # seconds between each.
      #
      # The pause is deliberate. discordrb already rate limits, but it does so reactively: once a bucket is exhausted
      # it sleeps the sending thread (and a global limit sleeps every thread) until the window resets. When many
      # servers restart on the same 3-hour cadence, reconnect together, and flush their queued XM8 notifications at
      # once, sending flat-out drives the workers straight into those sleeps and the queue stalls - blocking everything
      # else that needs to talk to Discord. Pacing keeps the send rate under discordrb's threshold so it rarely has to
      # intervene, and routing every send through this queue keeps that blocking I/O off the source threads.
      #
      # Fire-and-forget callers enqueue and return immediately. Callers that need the sent message back pass
      # +wait: true+ and block on the returned promise.
      #
      class DeliveryOverseer
        #
        # A queued send and the optional promise a worker fulfills with the delivered message once discordrb returns.
        #
        Envelope = Data.define(:message, :delivery_channel, :embed_message, :replying_to, :promise)

        # Number of workers draining the queue. Several so a worker parked in one of discordrb's per-channel rate-limit
        # sleeps doesn't stall delivery to every other channel.
        WORKER_COUNT = 4

        # Longest a blocking caller will wait for Discord to confirm a send.
        WAIT_TIMEOUT = 2.minutes.to_i

        def initialize(check_every: ESM.config.bot_delivery_overseer.check_every)
          @queue = Queue.new
          @check_every = check_every
          @workers = Array.new(WORKER_COUNT) { spawn_worker }
        end

        #
        # Enqueues a message for delivery.
        #
        # @param message [String, ESM::Embed] the message or embed to send
        # @param delivery_channel [Discordrb::Channel] the resolved destination channel
        # @param embed_message [String] optional text attached alongside an embed
        # @param replying_to [Discordrb::Message, nil] a message to reference in the reply
        # @param wait [Boolean] when true, returns a promise the caller can block on
        #
        # @return [Concurrent::IVar, nil] a promise resolving to the sent Discordrb::Message (or nil on failure) when
        #   +wait+ is true; nil otherwise
        #
        def add(message, delivery_channel, embed_message: "", replying_to: nil, wait: false)
          promise = Concurrent::IVar.new if wait

          @queue << Envelope.new(
            message:,
            delivery_channel:,
            embed_message:,
            replying_to:,
            promise:
          )

          promise
        end

        private

        def spawn_worker
          Thread.new do
            while (envelope = @queue.pop)
              deliver(envelope)
              sleep(@check_every)
            end
          end
        end

        def deliver(envelope)
          message = ESM.discord_bot.__deliver(
            envelope.message,
            envelope.delivery_channel,
            embed_message: envelope.embed_message,
            replying_to: envelope.replying_to
          )

          envelope.promise&.set(message)
        rescue => e
          error!(e)

          envelope.promise&.set(nil)
        end
      end
    end
  end
end
All opinions represented herein are my own
- © 2024 - 2026 itsthedevman
- build 43aa0d7