# frozen_string_literal: true
class SessionManager
class Timeout < StandardError; end
def initialize(blather, id_msg, timeout: 5, error_if: nil)
@blather = blather
@sessions = {}
@id_msg = id_msg
@timeout = timeout
@error_if = error_if
end
def promise_for(stanza)
id = "#{stanza.to.stripped}/#{stanza.public_send(@id_msg)}"
@sessions.fetch(id) do
@sessions[id] = EMPromise.new
EM.add_timer(@timeout) do
@sessions.delete(id)&.reject(Timeout.new)
end
@sessions[id]
end
end
def write(stanza)
promise = promise_for(stanza)
@blather << stanza
promise
end
def fulfill(stanza)
id = "#{stanza.from.stripped}/#{stanza.public_send(@id_msg)}"
if stanza.error? || @error_if&.call(stanza)
@sessions.delete(id)&.reject(stanza)
else
@sessions.delete(id)&.fulfill(stanza)
end
end
end