Class: RSMP::Site

Inherits:
Node
  • Object
show all
Includes:
Components
Defined in:
lib/rsmp/site.rb

Direct Known Subclasses

Tlc

Instance Attribute Summary collapse

Attributes included from Components

#components

Attributes inherited from Node

#archive, #clock, #deferred, #error_queue, #task

Attributes included from Logging

#archive

Instance Method Summary collapse

Methods included from Components

#add_component, #build_component, #find_component, #initialize_components, #setup_components

Methods inherited from Node

#author, #check_required_settings, #defer, #do_deferred, #do_start, #exiting, #idle, #notify_error, #process_deferred, #restart, #start

Methods included from Inspect

#inspect, #inspector

Methods included from Wait

#wait_for

Methods included from Logging

#author, #initialize_logging, #log

Constructor Details

#initialize(options = {}) ⇒ Site

Returns a new instance of Site.


11
12
13
14
15
16
17
18
# File 'lib/rsmp/site.rb', line 11

def initialize options={}
  initialize_components
  handle_site_settings options
  super options
  @proxies = []
  @sleep_condition = Async::Notification.new
  @proxies_condition = Async::Notification.new
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.


9
10
11
# File 'lib/rsmp/site.rb', line 9

def logger
  @logger
end

#proxiesObject (readonly)

Returns the value of attribute proxies.


9
10
11
# File 'lib/rsmp/site.rb', line 9

def proxies
  @proxies
end

#rsmp_versionsObject (readonly)

Returns the value of attribute rsmp_versions.


9
10
11
# File 'lib/rsmp/site.rb', line 9

def rsmp_versions
  @rsmp_versions
end

#site_settingsObject (readonly)

Returns the value of attribute site_settings.


9
10
11
# File 'lib/rsmp/site.rb', line 9

def site_settings
  @site_settings
end

Instance Method Details

#aggregated_status_changed(component, options = {}) ⇒ Object


78
79
80
81
82
# File 'lib/rsmp/site.rb', line 78

def aggregated_status_changed component, options={}
  @proxies.each do |proxy|
    proxy.send_aggregated_status component, options
  end
end

#alarmObject


142
143
144
145
146
# File 'lib/rsmp/site.rb', line 142

def alarm
  @proxies.each do |proxy|
    proxy.stop
  end
end

#build_proxy(settings) ⇒ Object


74
75
76
# File 'lib/rsmp/site.rb', line 74

def build_proxy settings
  SupervisorProxy.new settings
end

#check_sxl_versionObject


53
54
55
56
57
# File 'lib/rsmp/site.rb', line 53

def check_sxl_version
  sxl = @site_settings['sxl']
  version = @site_settings['sxl_version']
  RSMP::Schemer::find_schema! sxl, version, lenient: true
end

#connect_to_supervisor(task, supervisor_settings) ⇒ Object


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rsmp/site.rb', line 84

def connect_to_supervisor task, supervisor_settings
  proxy = build_proxy({
    site: self,
    task: @task,
    settings: @site_settings, 
    ip: supervisor_settings['ip'],
    port: supervisor_settings['port'],
    logger: @logger,
    archive: @archive
  })
  @proxies << proxy
  @proxies_condition.signal
  run_site_proxy task, proxy
ensure
  @proxies.delete proxy
  @proxies_condition.signal
end

#find_supervisor(ip) ⇒ Object


156
157
158
159
160
161
# File 'lib/rsmp/site.rb', line 156

def find_supervisor ip
  @proxies.each do |supervisor|
    return supervisor if ip == :any || supervisor.ip == ip
  end
  nil
end

#handle_site_settings(options = {}) ⇒ Object


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rsmp/site.rb', line 24

def handle_site_settings options={}
  defaults = {
    'site_id' => 'RN+SI0001',
    'supervisors' => [
      { 'ip' => '127.0.0.1', 'port' => 12111 }
    ],
    'rsmp_versions' => 'all',
    'sxl' => 'tlc',
    'sxl_version' => '1.0.15',
    'intervals' => {
      'timer' => 0.1,
      'watchdog' => 1,
      'reconnect' => 0.1
    },
    'timeouts' => {
      'watchdog' => 2,
      'acknowledgement' => 2
    },
    'send_after_connect' => true,
    'components' => {
      'C1' => {}
    }
  }
  
  @site_settings = defaults.deep_merge options[:site_settings]
  check_sxl_version
  setup_components @site_settings['components']
end

#reconnectObject


59
60
61
# File 'lib/rsmp/site.rb', line 59

def reconnect
  @sleep_condition.signal
end

#run_site_proxy(task, proxy) ⇒ Object


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rsmp/site.rb', line 102

def run_site_proxy task, proxy
  loop do
    proxy.run       # run until disconnected
  rescue IOError => e
    log "Stream error: #{e}", level: :warning
  rescue StandardError => e
    notify_error e, level: :internal
  ensure
    begin
      if @site_settings['intervals']['watchdog'] != :no
        # sleep until waken by reconnect() or the reconnect interval passed
        proxy.set_state :wait_for_reconnect
        task.with_timeout(@site_settings['intervals']['watchdog']) do
          @sleep_condition.wait
        end
      else
        proxy.set_state :cannot_connect
        break
      end
    rescue Async::TimeoutError
      # ignore
    end
  end
end

#site_idObject


20
21
22
# File 'lib/rsmp/site.rb', line 20

def site_id
  @site_settings['site_id']
end

#start_actionObject


63
64
65
66
67
68
69
70
71
72
# File 'lib/rsmp/site.rb', line 63

def start_action
  @site_settings["supervisors"].each do |supervisor_settings|
    @task.async do |task|
      task.annotate "site proxy"
      connect_to_supervisor task, supervisor_settings
    rescue StandardError => e
      notify_error e, level: :internal
    end
  end
end

#startingObject


136
137
138
139
140
# File 'lib/rsmp/site.rb', line 136

def starting
  log "Starting site #{@site_settings["site_id"]}",
      level: :info,
      timestamp: @clock.now
end

#stopObject


127
128
129
130
131
132
133
134
# File 'lib/rsmp/site.rb', line 127

def stop
  log "Stopping site #{@site_settings["site_id"]}", level: :info
  @proxies.each do |proxy|
    proxy.stop
  end
  @proxies.clear
  super
end

#wait_for_supervisor(ip, timeout) ⇒ Object


148
149
150
151
152
153
154
# File 'lib/rsmp/site.rb', line 148

def wait_for_supervisor ip, timeout
  supervisor = find_supervisor ip
  return supervisor if supervisor
  wait_for(@proxy_condition,timeout) { find_supervisor ip }
rescue Async::TimeoutError
  raise RSMP::TimeoutError.new "Supervisor '#{ip}' did not connect within #{timeout}s"
end