module AutoopJoinProbe
AutoopJoinProbe — batch join lag/user probes per nick across simultaneous channel joins. Public: attach, process_lag_probe_reply!, process_user_pong_reply!, stale_announcements, finalize_batch! Depends: IrcLag, IrcUserPing, Normalize Tests: test/lib/autoop_join_probe_test.rb, test/plugins/autoop_test.rb
Public Instance Methods
Source
# File lib/autoop_join_probe.rb, line 33 def active_batch_for_nick?(nick) active_by_nick.key?(Normalize.nick(nick).downcase) end
Source
# File lib/autoop_join_probe.rb, line 21 def active_by_nick @active_by_nick ||= {} end
Source
# File lib/autoop_join_probe.rb, line 37 def attach(nick:, count:, channel:, server:, sent_at:) nick = Normalize.nick(nick) nick_key = nick.downcase existing_token = active_by_nick[nick_key] if existing_token && batches[existing_token] batches[existing_token][:entries] << { count: count, channel: channel } return batch_result(existing_token, send_probes: false, nick: nick, server: server) end token = next_batch_token(sent_at) active_by_nick[nick_key] = token batches[token] = { sent_at: sent_at, nick: nick, server: server, lag_ms: nil, ping_ms: nil, entries: [{ count: count, channel: channel }] } IrcLag.register_pending_reply( token, sent_at: sent_at, nick: nick, count: count, channel: channel, server: server, ping_sent_at: sent_at ) batch_result(token, send_probes: true, sent_at: sent_at, nick: nick, server: server) end
Source
# File lib/autoop_join_probe.rb, line 29 def batch_entries(batch_token) batches[batch_token]&.dig(:entries) end
Source
# File lib/autoop_join_probe.rb, line 143 def batch_ready?(batch_token, batch) !lag_ms_for_batch(batch_token, batch).nil? && !ping_ms_for_batch(batch_token, batch).nil? end
Source
# File lib/autoop_join_probe.rb, line 121 def batch_result(batch_token, send_probes:, sent_at: nil, nick:, server:) batch = batches[batch_token] { batch_token: batch_token, send_probes: send_probes, sent_at: sent_at || batch[:sent_at], nick: nick, server: server } end
Source
# File lib/autoop_join_probe.rb, line 161 def build_items(batch_token:, batch:, lag_ms:, ping_ms: nil) ping_ms ||= ping_ms_for_batch(batch_token, batch) batch[:entries].map do |entry| pending = { nick: batch[:nick], count: entry[:count], channel: entry[:channel], server: batch[:server], ping_ms: ping_ms, lag_ms: lag_ms } { batch_token: batch_token, lag_ms: lag_ms, pending: pending, announcement: nil } end end
Source
# File lib/autoop_join_probe.rb, line 108 def finalize_batch!(batch_token) batch = batches.delete(batch_token) return unless batch active_by_nick.delete(batch[:nick].downcase) IrcLag.take_pending_reply(batch_token) IrcUserPing.remove!(nick: batch[:nick]) end
Source
# File lib/autoop_join_probe.rb, line 147 def lag_ms_for_batch(batch_token, batch) batch[:lag_ms] || IrcLag.pending_replies[batch_token]&.dig(:lag_ms) end
Source
# File lib/autoop_join_probe.rb, line 117 def lag_probe_command(batch_token) "#{IrcLag::LAG_PROBE_PREFIX}#{batch_token}" end
Source
# File lib/autoop_join_probe.rb, line 155 def next_batch_token(sent_at) @batch_seq ||= 0 @batch_seq += 1 IrcLag.lag_probe_token(sent_at) + @batch_seq end
Source
# File lib/autoop_join_probe.rb, line 151 def ping_ms_for_batch(batch_token, batch) batch[:ping_ms] || IrcLag.pending_replies[batch_token]&.dig(:ping_ms) end
Source
# File lib/autoop_join_probe.rb, line 69 def process_lag_probe_reply!(params, received_at:) result = IrcLag.record_lag_probe_reply!(params, received_at: received_at) return [] unless result batch = batches[result[:token]] return [] unless batch batch[:lag_ms] = result[:ms] ready_results(batch_token: result[:token], batch: batch) end
Source
# File lib/autoop_join_probe.rb, line 80 def process_user_pong_reply!(params:, received_at:) result = IrcUserPing.record_pong_reply!(params: params, received_at: received_at) return [] unless result batch = batches[result[:context]] return [] unless batch batch[:ping_ms] = result[:ms] IrcLag.update_pending_ping!(result[:context], ping_ms: result[:ms]) ready_results(batch_token: result[:context], batch: batch) end
Source
# File lib/autoop_join_probe.rb, line 132 def ready_results(batch_token:, batch:) return [] unless batch_ready?(batch_token, batch) build_items( batch_token: batch_token, batch: batch, lag_ms: lag_ms_for_batch(batch_token, batch), ping_ms: ping_ms_for_batch(batch_token, batch) ) end
Source
# File lib/autoop_join_probe.rb, line 15 def reset! @active_by_nick = {} @batches = {} @batch_seq = 0 end
Source
# File lib/autoop_join_probe.rb, line 92 def stale_announcements(max_age_sec:, now: Process.clock_gettime(Process::CLOCK_MONOTONIC)) batches.flat_map do |batch_token, batch| lag_ms = lag_ms_for_batch(batch_token, batch) next [] unless lag_ms next [] unless batch[:ping_ms].nil? next [] if (now - batch[:sent_at]) < max_age_sec build_items( batch_token: batch_token, batch: batch, lag_ms: lag_ms, ping_ms: batch[:ping_ms] ) end end