Class: Terminalwire::V2::Server::Connection

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

Overview

The server-role protocol state machine. Sans-IO: the application feeds it incoming frames via #receive (getting back directives) and asks it to build outgoing frames via the helper methods. No sockets, threads, or clock.

A "directive" returned from #receive is one of:

[:send, frame_hash]              — write this frame to the transport
[:event, name_symbol, payload]   — a domain event for the application

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server_min: Protocol::MIN_VERSION, server_max: Protocol::MAX_VERSION, server_capabilities: Protocol::CAPABILITIES, mux: Mux.new) ⇒ Connection

Returns a new instance of Connection.



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/terminalwire/v2/server/connection.rb', line 15

def initialize(server_min: Protocol::MIN_VERSION,
               server_max: Protocol::MAX_VERSION,
               server_capabilities: Protocol::CAPABILITIES,
               mux: Mux.new)
  @server_min = server_min
  @server_max = server_max
  @server_capabilities = server_capabilities
  @mux = mux
  @state = :awaiting_hello
  @protocol = nil
  @capabilities = []
end

Instance Attribute Details

#capabilitiesObject (readonly)

Returns the value of attribute capabilities.



13
14
15
# File 'lib/terminalwire/v2/server/connection.rb', line 13

def capabilities
  @capabilities
end

#protocolObject (readonly)

Returns the value of attribute protocol.



13
14
15
# File 'lib/terminalwire/v2/server/connection.rb', line 13

def protocol
  @protocol
end

#stateObject (readonly)

Returns the value of attribute state.



13
14
15
# File 'lib/terminalwire/v2/server/connection.rb', line 13

def state
  @state
end

Instance Method Details

#call(resource, method, params = {}) ⇒ Object

Issue a resource request. Returns [sid, frame]; the response will arrive later via #receive as [:event, :response, ...].



65
66
67
68
69
70
# File 'lib/terminalwire/v2/server/connection.rb', line 65

def call(resource, method, params = {})
  require_ready!
  sid = @mux.allocate
  @mux.register(sid, { resource: resource, method: method })
  [sid, Frames.request(sid: sid, resource: resource.to_s, method: method.to_s, params: params)]
end

#close_stream(sid) ⇒ Object



58
59
60
61
# File 'lib/terminalwire/v2/server/connection.rb', line 58

def close_stream(sid)
  require_ready!
  Frames.close(sid: sid)
end

#exit(status = 0) ⇒ Object



72
73
74
75
# File 'lib/terminalwire/v2/server/connection.rb', line 72

def exit(status = 0)
  @state = :closed
  Frames.exit(status: status)
end

#open_stream(stream, mode: nil) ⇒ Object

Open a stream (:stdout/:stderr output, or a stdin-raw input stream with a line-discipline mode). Returns [sid, frame].



46
47
48
49
50
# File 'lib/terminalwire/v2/server/connection.rb', line 46

def open_stream(stream, mode: nil)
  require_ready!
  sid = @mux.allocate
  [sid, Frames.open(sid: sid, stream: stream.to_s, mode: mode)]
end

#ready?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/terminalwire/v2/server/connection.rb', line 28

def ready?
  @state == :ready
end

#receive(frame) ⇒ Object

Feed one incoming frame. Returns an Array of directives (see class docs).



33
34
35
36
37
38
39
40
# File 'lib/terminalwire/v2/server/connection.rb', line 33

def receive(frame)
  case @state
  when :awaiting_hello then on_hello(frame)
  when :ready          then on_ready(frame)
  else
    raise ProtocolError, "received #{frame["t"].inspect} while #{@state}"
  end
end

#write(sid, bytes) ⇒ Object

Build a data frame for an open output stream.



53
54
55
56
# File 'lib/terminalwire/v2/server/connection.rb', line 53

def write(sid, bytes)
  require_ready!
  Frames.data(sid: sid, bytes: bytes)
end