Class: Textus::Protocol::Session

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/textus/protocol/session.rb

Defined Under Namespace

Classes: Bridge, Context

Constant Summary collapse

DOMAIN_VERBS =
(VerbRegistry::ENTRY_VERBS + VerbRegistry::OPS_VERBS).to_set.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bridge:, context:) ⇒ Session

Returns a new instance of Session.



32
33
34
35
# File 'lib/textus/protocol/session.rb', line 32

def initialize(bridge:, context:)
  @bridge = bridge
  @context = context
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/textus/protocol/session.rb', line 37

def method_missing(name, *args, **kwargs)
  if DOMAIN_VERBS.include?(name)
    raise ArgumentError.new("#{name} accepts keyword arguments only") unless args.empty?

    return bridge.dispatch(role.to_sym, name, kwargs, call: context.call)
  end

  return bridge.public_send(name, *args, **kwargs) if bridge.respond_to?(name)

  super
end

Instance Attribute Details

#bridgeObject (readonly)

Returns the value of attribute bridge.



8
9
10
# File 'lib/textus/protocol/session.rb', line 8

def bridge
  @bridge
end

#contextObject (readonly)

Returns the value of attribute context.



8
9
10
# File 'lib/textus/protocol/session.rb', line 8

def context
  @context
end

Class Method Details

.open(root, role: Value::Role::DEFAULT, correlation_id: nil, dry_run: false) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/textus/protocol/session.rb', line 16

def self.open(root, role: Value::Role::DEFAULT, correlation_id: nil, dry_run: false)
  root = File.expand_path(root)
  container = Protocol::Builder.new.call(root)
  gate = container.gate
  bridge = Session::Bridge.new(container:, gate:)
  context = Session::Context.new(
    role: role.to_s,
    correlation_id: correlation_id || SecureRandom.uuid,
    dry_run: dry_run,
    cursor: container.store.audit_log.latest[:seq],
    contract_etag: Value::Etag.for_contract(bridge.layout),
    propose_lane: container.manifest.policy.propose_lane_for(role.to_s),
  )
  new(bridge:, context:)
end

Instance Method Details

#advance_cursor(new_cursor) ⇒ Object



69
70
71
72
# File 'lib/textus/protocol/session.rb', line 69

def advance_cursor(new_cursor)
  @context = context.with(cursor: new_cursor)
  self
end

#check_etag!(observed_etag) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/textus/protocol/session.rb', line 74

def check_etag!(observed_etag)
  return if observed_etag == contract_etag

  raise Textus::ContractDrift.new(
    "contract changed (was #{short_etag(contract_etag)}, now #{short_etag(observed_etag)})",
  )
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/textus/protocol/session.rb', line 49

def respond_to_missing?(name, include_private = false)
  DOMAIN_VERBS.include?(name) || bridge.respond_to?(name) || super
end

#with_correlation_id(cid) ⇒ Object



53
54
55
# File 'lib/textus/protocol/session.rb', line 53

def with_correlation_id(cid)
  self.class.new(bridge:, context: context.with(correlation_id: cid))
end

#with_role(new_role) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/textus/protocol/session.rb', line 57

def with_role(new_role)
  self.class.new(
    bridge:,
    context: context.with(
      role: new_role.to_s,
      cursor: container.store.audit_log.latest[:seq],
      contract_etag: Value::Etag.for_contract(container.layout),
      propose_lane: manifest.policy.propose_lane_for(new_role.to_s),
    ),
  )
end