Class: Terminalwire::V2::Server::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/terminalwire/v2/server/session.rb

Overview

Adapts a callback/event-loop websocket endpoint to the blocking Handler. The endpoint supplies an on_send sink for outgoing frames and forwards each incoming frame to #receive; the CLI runs on a background thread. This is the seam an ActionCable channel or an async-websocket Rack endpoint plugs into (see ../../../README.md).

session = Terminalwire::V2::Server::Session.start(
cli_class: MyCLI,
on_send:   ->(bytes) { websocket.send_binary(bytes) }
)
websocket.on_message { |bytes| session.receive(bytes) }
websocket.on_close   { session.close }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cli_class:, on_send:, report: nil, verbose: false) ⇒ Session

Returns a new instance of Session.



22
23
24
25
# File 'lib/terminalwire/v2/server/session.rb', line 22

def initialize(cli_class:, on_send:, report: nil, verbose: false)
  @transport = Transport::Queue.new(sink: on_send)
  @handler = Handler.new(cli_class: cli_class, report: report, verbose: verbose)
end

Class Method Details

.start(cli_class:, on_send:, report: nil, verbose: false) ⇒ Object



18
19
20
# File 'lib/terminalwire/v2/server/session.rb', line 18

def self.start(cli_class:, on_send:, report: nil, verbose: false)
  new(cli_class: cli_class, on_send: on_send, report: report, verbose: verbose).tap(&:start)
end

Instance Method Details

#closeObject

End the session and wait briefly for the worker to finish.



45
46
47
48
# File 'lib/terminalwire/v2/server/session.rb', line 45

def close
  @transport.close
  @thread&.join(2)
end

#receive(bytes) ⇒ Object

Forward a frame received from the client.



40
41
42
# File 'lib/terminalwire/v2/server/session.rb', line 40

def receive(bytes)
  @transport.deliver(bytes)
end

#startObject



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/terminalwire/v2/server/session.rb', line 27

def start
  @thread = Thread.new do
    @handler.call(transport: @transport)
  ensure
    # Once the worker is done (normal exit or error), close the transport so
    # any further frames the endpoint delivers are dropped instead of piling
    # up in the inbox behind a dead worker.
    @transport.close
  end
  self
end