Class: RSMP::Proxy

Inherits:
Object
  • Object
show all
Includes:
Distributor, Logging, Modules::Acknowledgements, Modules::Lifecycle, Modules::Receive, Modules::Send, Modules::State, Modules::Tasks, Modules::Versions, Modules::Watchdogs, Task
Defined in:
lib/rsmp/proxy/proxy.rb,
lib/rsmp/proxy/modules/send.rb,
lib/rsmp/proxy/modules/state.rb,
lib/rsmp/proxy/modules/tasks.rb,
lib/rsmp/proxy/modules/receive.rb,
lib/rsmp/proxy/modules/versions.rb,
lib/rsmp/proxy/modules/lifecycle.rb,
lib/rsmp/proxy/modules/watchdogs.rb,
lib/rsmp/proxy/modules/acknowledgements.rb

Overview

Represents a connection to a remote site or supervisor. Provides common connection lifecycle and message handling.

Direct Known Subclasses

SiteProxy, SupervisorProxy

Defined Under Namespace

Modules: Modules

Constant Summary collapse

WRAPPING_DELIMITER =
"\f".freeze

Instance Attribute Summary collapse

Attributes included from Task

#task

Attributes included from Distributor

#receivers

Attributes included from Logging

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Modules::Lifecycle

#begin_session, #close, #close_from_result, #close_socket, #close_stream, #connect!, #connection_end_failure, #disconnect, #disconnect!, #distribute_event, #publish_connection_attempt_failure, #stop_reader, #stop_subtasks, #stop_task, #stop_timer, #wait_for_reader

Methods included from Modules::Tasks

#connection_read_failure, #log_processing_statistics, #process_received_line, #processing_speed, #read_protocol_line, #run_reader, #run_timer, #session_active?, #session_tasks, #start_reader, #start_timer, #timer, #wait_for_session

Methods included from Modules::Versions

#advertised_core_versions, #check_core_version, #component_list_acknowledged, #configured_sxls, #core_3_3?, #core_versions, #extraneous_version, #normalized_core_versions, #primary_configured_sxl, #process_version, #send_legacy_version_response, #send_version, #send_version_message, #send_version_request, #send_version_response, #site_id_items, #sxl_request_items, #valid_sxl_response?, #validate_sxl_response!, #version_acknowledged, #version_items, #version_meets_requirement?, #version_message_attributes, #version_request_attributes, #version_response_sxls, #wire_core_version_aliases

Methods included from Modules::Receive

#expect_version_message, #peer_failure, #process_deferred, #process_incoming_message, #process_message, #process_packet, #publish_peer_failure, #reject_fatal_message, #reject_invalid_message, #reject_invalid_packet, #reject_malformed_packet, #reject_packet, #reject_processed_message, #should_validate_ingoing_message?, #verify_sequence, #will_not_handle

Methods included from Modules::Send

#apply_nts_message_attributes, #buffer_message, #buffer_or_fail, #disconnected_send_result, #invalid_outbound_result, #log_send, #prepare_message, #recover_write_failure, #send_generated_message, #send_message, #send_message!, #send_message_and_collect, #send_message_and_collect!, #write_message, #write_protocol

Methods included from Modules::Acknowledgements

#acknowledge, #acknowledged_first_ingoing, #acknowledged_first_outgoing, #check_ack_timeout, #check_ingoing_acknowledged, #check_outgoing_acknowledged, #dont_acknowledge, #dont_expect_acknowledgement, #expect_acknowledgement, #find_original_for_message, #log_acknowledgement_for_original, #log_acknowledgement_for_unknown, #process_ack, #process_not_ack, #status_subscribe_acknowledged

Methods included from Modules::Watchdogs

#check_watchdog_timeout, #process_watchdog, #send_watchdog, #start_watchdog, #stop_watchdog, #watchdog_send_timer, #with_watchdog_disabled

Methods included from Modules::State

#handshake_complete, #wait_for_state, #wait_for_state!

Methods included from Task

#initialize_task, #restart, #run, #start, #stop, #stop_subtasks, #stop_task, #task_status, #wait, #wait_for_condition, #wait_for_condition!, #wait_for_termination

Methods included from Distributor

#add_receiver, #clear_deferred_distribution, #distribute, #distribute_event, #distribute_immediately, #distribute_queued, #initialize_distributor, #remove_receiver, #with_deferred_distribution

Methods included from Logging

#initialize_logging

Constructor Details

#initialize(options) ⇒ Proxy

Returns a new instance of Proxy.



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rsmp/proxy/proxy.rb', line 25

def initialize(options)
  @node = options[:node]
  options[:logger] = @node&.logger unless options[:logger] # default to node logger
  initialize_logging options
  initialize_distributor
  initialize_task
  setup options
  clear
  @state = :disconnected
  @state_condition = Async::Notification.new
  @session_id = 0
  @session_closed = true
end

Instance Attribute Details

#accepted_sxlsObject (readonly)

Returns the value of attribute accepted_sxls.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def accepted_sxls
  @accepted_sxls
end

#archiveObject (readonly)

Returns the value of attribute archive.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def archive
  @archive
end

#collectorObject (readonly)

Returns the value of attribute collector.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def collector
  @collector
end

#connection_infoObject (readonly)

Returns the value of attribute connection_info.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def connection_info
  @connection_info
end

#core_versionObject (readonly)

Returns the value of attribute core_version.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def core_version
  @core_version
end

#core_version_stringObject (readonly)

Returns the value of attribute core_version_string.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def core_version_string
  @core_version_string
end

#ipObject (readonly)

Returns the value of attribute ip.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def ip
  @ip
end

#nodeObject (readonly)

Returns the value of attribute node.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def node
  @node
end

#portObject (readonly)

Returns the value of attribute port.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def port
  @port
end

#rejected_sxlsObject (readonly)

Returns the value of attribute rejected_sxls.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def rejected_sxls
  @rejected_sxls
end

#session_idObject (readonly)

Returns the value of attribute session_id.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def session_id
  @session_id
end

#site_settingsObject (readonly)

Returns the value of attribute site_settings.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def site_settings
  @site_settings
end

#stateObject

Returns the value of attribute state.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def state
  @state
end

#sxl_interfacesObject (readonly)

Returns the value of attribute sxl_interfaces.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def sxl_interfaces
  @sxl_interfaces
end

#sxlsObject (readonly)

Returns the value of attribute sxls.



21
22
23
# File 'lib/rsmp/proxy/proxy.rb', line 21

def sxls
  @sxls
end

Class Method Details

.version_meets_requirement?(version, requirement) ⇒ Boolean

Use Gem class to check version requirement Requirement must be a string like '1.1.0', '>=1.0.3' or '<2.1.4', or list of strings, like ['<=1.4.0','<1.5.0']

Returns:



195
196
197
# File 'lib/rsmp/proxy/proxy.rb', line 195

def self.version_meets_requirement?(version, requirement)
  Modules::Versions.version_meets_requirement?(version, requirement)
end

Instance Method Details

#authorObject



148
149
150
# File 'lib/rsmp/proxy/proxy.rb', line 148

def author
  @node.site_id
end

#build_sxl_interfacesObject



152
153
154
155
156
# File 'lib/rsmp/proxy/proxy.rb', line 152

def build_sxl_interfaces
  @sxl_interfaces = accepted_sxls.to_h do |sxl|
    [sxl['name'], RSMP::SXL::Registry.build_for(self, sxl)]
  end
end

#clearObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rsmp/proxy/proxy.rb', line 75

def clear
  @awaiting_acknowledgement = {}
  @latest_watchdog_received = nil
  @watchdog_started = false
  @version_determined = false
  @ingoing_acknowledged = {}
  @outgoing_acknowledged = {}
  @latest_watchdog_send_at = nil
  @component_list_received = false
  @outgoing_watchdog_acknowledged = false
  @sxl_interfaces = {}

  @acknowledgements = {}
  @acknowledgement_condition = Async::Notification.new
end

#clockObject



115
116
117
# File 'lib/rsmp/proxy/proxy.rb', line 115

def clock
  @node.clock
end

#command_codes(message) ⇒ Object



180
181
182
# File 'lib/rsmp/proxy/proxy.rb', line 180

def command_codes(message)
  command_items(message).map { |item| item['cCI'] }.compact.uniq
end

#command_items(message) ⇒ Object



175
176
177
178
# File 'lib/rsmp/proxy/proxy.rb', line 175

def command_items(message)
  key = message.is_a?(CommandResponse) ? 'rvs' : 'arg'
  message.attributes[key] || []
end

#connected?Boolean

Returns:



53
54
55
# File 'lib/rsmp/proxy/proxy.rb', line 53

def connected?
  @state == :connected || @state == :ready
end

#disconnected?Boolean

Returns:



57
58
59
# File 'lib/rsmp/proxy/proxy.rb', line 57

def disconnected?
  @state == :disconnected
end

#inspectObject



39
40
41
# File 'lib/rsmp/proxy/proxy.rb', line 39

def inspect
  "#<#{self.class.name}:#{object_id} state:#{state}}>"
end

#log(str, options = {}) ⇒ Object



119
120
121
# File 'lib/rsmp/proxy/proxy.rb', line 119

def log(str, options = {})
  super(str, options.merge(ip: @ip, port: @port, site_id: @site_id))
end

#multiple_command_codes?(message) ⇒ Boolean

Returns:



184
185
186
# File 'lib/rsmp/proxy/proxy.rb', line 184

def multiple_command_codes?(message)
  command_codes(message).size > 1
end

#nowObject



43
44
45
# File 'lib/rsmp/proxy/proxy.rb', line 43

def now
  node.now
end

#primary_sxlObject



136
137
138
# File 'lib/rsmp/proxy/proxy.rb', line 136

def primary_sxl
  accepted_sxls.first || sxls.first
end

#ready?Boolean

State management methods

Returns:



49
50
51
# File 'lib/rsmp/proxy/proxy.rb', line 49

def ready?
  @state == :ready
end

#receive_alarms?Boolean

Returns:



132
133
134
# File 'lib/rsmp/proxy/proxy.rb', line 132

def receive_alarms?
  @receive_alarms != false
end

#reject_multiple_command_codes(message) ⇒ Object



188
189
190
# File 'lib/rsmp/proxy/proxy.rb', line 188

def reject_multiple_command_codes(message)
  dont_acknowledge message, 'Rejected', 'more than one command code in a single command message'
end

#revive(options) ⇒ Object

revive after a reconnect



92
93
94
# File 'lib/rsmp/proxy/proxy.rb', line 92

def revive(options)
  setup options
end

#schemasObject



123
124
125
126
127
128
129
130
# File 'lib/rsmp/proxy/proxy.rb', line 123

def schemas
  schemas = { core: RSMP::Schema.latest_core_version } # use latest core
  schemas[:core] = core_version if core_version
  accepted_sxls.each do |sxl|
    schemas[sxl['name'].to_sym] = RSMP::Schema.sanitize_version(sxl['version'].to_s)
  end
  schemas
end

#setup(options) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rsmp/proxy/proxy.rb', line 96

def setup(options)
  @settings = options[:settings]
  @socket = options[:socket]
  @stream = options[:stream]
  @protocol = options[:protocol]
  @ip = options[:ip]
  @port = options[:port]
  @connection_info = options[:info]
  @sxls = []
  @accepted_sxls = []
  @rejected_sxls = []
  @receive_alarms = true
  @site_settings = nil # can't pick until we know the site id
  return unless options[:collect]

  @collector = RSMP::Collector.new self, options[:collect]
  @collector.start
end

#state_changedObject

the state changed override to to things like notifications



71
72
73
# File 'lib/rsmp/proxy/proxy.rb', line 71

def state_changed
  @state_condition.signal @state
end

#sxlObject



140
141
142
# File 'lib/rsmp/proxy/proxy.rb', line 140

def sxl
  primary_sxl && primary_sxl['name']
end

#sxl_interface(name) ⇒ Object



158
159
160
161
162
# File 'lib/rsmp/proxy/proxy.rb', line 158

def sxl_interface(name)
  sxl_interfaces.fetch(name.to_s) do
    raise RSMP::Schema::UnknownSchemaTypeError, "SXL #{name} is not accepted on this connection"
  end
end

#sxl_interface_for(message) ⇒ Object



168
169
170
171
172
173
# File 'lib/rsmp/proxy/proxy.rb', line 168

def sxl_interface_for(message)
  resolved = RSMP::Schema.resolve_sxl(message.attributes, schemas: schemas)
  return unless resolved

  sxl_interface resolved.first
end

#sxl_versionObject



144
145
146
# File 'lib/rsmp/proxy/proxy.rb', line 144

def sxl_version
  primary_sxl && primary_sxl['version']
end

#tlcObject



164
165
166
# File 'lib/rsmp/proxy/proxy.rb', line 164

def tlc
  sxl_interface 'tlc'
end