automate-em 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LGPL3-LICENSE +165 -0
- data/README.textile +48 -0
- data/Rakefile +40 -0
- data/app/models/control_system.rb +20 -0
- data/app/models/controller_device.rb +21 -0
- data/app/models/controller_http_service.rb +17 -0
- data/app/models/controller_logic.rb +5 -0
- data/app/models/controller_zone.rb +10 -0
- data/app/models/dependency.rb +20 -0
- data/app/models/server.rb +12 -0
- data/app/models/setting.rb +38 -0
- data/app/models/trusted_device.rb +63 -0
- data/app/models/user_zone.rb +10 -0
- data/app/models/zone.rb +16 -0
- data/db/migrate/20111001022500_init.rb +147 -0
- data/db/migrate/20111017213801_one_time_key.rb +9 -0
- data/db/migrate/20111021071632_encrypt_setting.rb +9 -0
- data/db/migrate/20111110075444_servers.rb +15 -0
- data/db/migrate/20111114074538_default_port.rb +9 -0
- data/db/migrate/20111122073055_makebreak.rb +9 -0
- data/db/migrate/20111211062846_create_controller_http_services.rb +18 -0
- data/lib/automate-em.rb +155 -0
- data/lib/automate-em/constants.rb +6 -0
- data/lib/automate-em/core/communicator.rb +318 -0
- data/lib/automate-em/core/modules.rb +373 -0
- data/lib/automate-em/core/resolver_pool.rb +76 -0
- data/lib/automate-em/core/system.rb +356 -0
- data/lib/automate-em/device/datagram_server.rb +111 -0
- data/lib/automate-em/device/device.rb +140 -0
- data/lib/automate-em/device/device_connection.rb +689 -0
- data/lib/automate-em/device/tcp_control.rb +210 -0
- data/lib/automate-em/engine.rb +36 -0
- data/lib/automate-em/interfaces/OLD CODE/deferred.rb +67 -0
- data/lib/automate-em/interfaces/OLD CODE/telnet/ansi.rb +137 -0
- data/lib/automate-em/interfaces/OLD CODE/telnet/telnet.rb +137 -0
- data/lib/automate-em/interfaces/html5.rb +302 -0
- data/lib/automate-em/logic/logic.rb +76 -0
- data/lib/automate-em/service/http_service.rb +584 -0
- data/lib/automate-em/service/service.rb +48 -0
- data/lib/automate-em/status.rb +89 -0
- data/lib/automate-em/utilities.rb +195 -0
- data/lib/automate-em/version.rb +3 -0
- data/lib/generators/module/USAGE +8 -0
- data/lib/generators/module/module_generator.rb +47 -0
- data/lib/tasks/automate-em_tasks.rake +5 -0
- data/test/automate-em_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- metadata +328 -0
@@ -0,0 +1,584 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'atomic'
|
3
|
+
|
4
|
+
|
5
|
+
#
|
6
|
+
# Include by default (keep it simple for developers)
|
7
|
+
#
|
8
|
+
require 'em-http/middleware/oauth'
|
9
|
+
require 'em-http/middleware/json_response'
|
10
|
+
|
11
|
+
|
12
|
+
class HttpDebugInspector
|
13
|
+
|
14
|
+
def request(client, head, body)
|
15
|
+
AutomateEm::System.logger.debug "HTTP request #{client.req.method} #{client.req.uri} #{head.inspect}:#{body.inspect}"
|
16
|
+
[head,body]
|
17
|
+
end
|
18
|
+
|
19
|
+
def response(resp)
|
20
|
+
AutomateEm::System.logger.debug "HTTP Response #{resp.response.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# This contains the basic constructs required for
|
27
|
+
# serialised comms over TCP and UDP
|
28
|
+
# => TODO:: SSL
|
29
|
+
#
|
30
|
+
module AutomateEm
|
31
|
+
class HttpService
|
32
|
+
VERBS = [:get, :post, :put, :delete, :head]
|
33
|
+
|
34
|
+
def initialize(parent, settings)
|
35
|
+
|
36
|
+
@config = {
|
37
|
+
:priority_bonus => 20,
|
38
|
+
|
39
|
+
|
40
|
+
:connect_timeout => 5,
|
41
|
+
:inactivity_timeout => 10
|
42
|
+
# :ssl
|
43
|
+
# :bind
|
44
|
+
# :proxy
|
45
|
+
}
|
46
|
+
@uri = URI.parse(settings.uri)
|
47
|
+
@config[:ssl] = parent.certificates if parent.respond_to?(:certificates)
|
48
|
+
#@connection = EventMachine::HttpRequest.new(@uri, @config)
|
49
|
+
|
50
|
+
@default_request_options = {
|
51
|
+
:wait => true, # Wait for response
|
52
|
+
:delay => 0, # Delay next request by x.y seconds
|
53
|
+
:delay_on_recieve => 0, # Delay next request after a recieve by x.y seconds (only works when we are waiting for responses)
|
54
|
+
#:emit
|
55
|
+
:retries => 2,
|
56
|
+
:priority => 50,
|
57
|
+
|
58
|
+
#
|
59
|
+
# EM:http related
|
60
|
+
#
|
61
|
+
# query
|
62
|
+
# body
|
63
|
+
# custom_client => block
|
64
|
+
:path => '/',
|
65
|
+
#file => path to file for streaming
|
66
|
+
#query
|
67
|
+
#
|
68
|
+
:keepalive => true,
|
69
|
+
:redirects => 0,
|
70
|
+
:verb => :get,
|
71
|
+
:stream => false, # send chunked data
|
72
|
+
#:stream_closed => block
|
73
|
+
#:headers
|
74
|
+
|
75
|
+
#:callback => nil, # Alternative to the received function
|
76
|
+
#:errback => nil,
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
#
|
81
|
+
# Queues
|
82
|
+
#
|
83
|
+
@task_queue = EM::Queue.new # basically we add tasks here that we want to run in a strict order
|
84
|
+
@wait_queue = EM::Queue.new
|
85
|
+
@send_queue = EM::PriorityQueue.new(:fifo => true) {|x,y| x < y} # regular priority
|
86
|
+
|
87
|
+
#
|
88
|
+
# Named commands
|
89
|
+
# Allowing for state control
|
90
|
+
#
|
91
|
+
@named_commands = {}
|
92
|
+
|
93
|
+
|
94
|
+
#
|
95
|
+
# Locks
|
96
|
+
#
|
97
|
+
@received_lock = Mutex.new
|
98
|
+
@task_lock = Mutex.new
|
99
|
+
@status_lock = Mutex.new
|
100
|
+
@send_monitor = Object.new.extend(MonitorMixin)
|
101
|
+
|
102
|
+
|
103
|
+
#
|
104
|
+
# State
|
105
|
+
#
|
106
|
+
@last_sent_at = 0.0
|
107
|
+
@last_recieve_at = 0.0
|
108
|
+
|
109
|
+
|
110
|
+
#
|
111
|
+
# Configure links between objects
|
112
|
+
#
|
113
|
+
@parent = parent
|
114
|
+
@parent.setbase(self)
|
115
|
+
@shutting_down = Atomic.new(false)
|
116
|
+
|
117
|
+
|
118
|
+
#
|
119
|
+
# Task event loop
|
120
|
+
#
|
121
|
+
@task_queue_proc = Proc.new do |task|
|
122
|
+
if !@shutting_down.value
|
123
|
+
EM.defer do
|
124
|
+
begin
|
125
|
+
@task_lock.synchronize {
|
126
|
+
task.call
|
127
|
+
}
|
128
|
+
rescue => e
|
129
|
+
AutomateEm.print_error(logger, e, {
|
130
|
+
:message => "module #{@parent.class} in http_service.rb : error in task loop",
|
131
|
+
:level => Logger::ERROR
|
132
|
+
})
|
133
|
+
ensure
|
134
|
+
ActiveRecord::Base.clear_active_connections!
|
135
|
+
@task_queue.pop &@task_queue_proc # First task is ready
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
@task_queue.pop &@task_queue_proc # First task is ready
|
141
|
+
|
142
|
+
|
143
|
+
#
|
144
|
+
# send loop
|
145
|
+
#
|
146
|
+
@wait_queue_proc = Proc.new do |ignore|
|
147
|
+
if ignore != :shutdown
|
148
|
+
|
149
|
+
@send_queue.pop {|command|
|
150
|
+
if command != :shutdown
|
151
|
+
|
152
|
+
begin
|
153
|
+
|
154
|
+
process = true
|
155
|
+
if command[:name].present?
|
156
|
+
name = command[:name]
|
157
|
+
@named_commands[name][0].pop # Extract the command data
|
158
|
+
command = @named_commands[name][1]
|
159
|
+
|
160
|
+
if @named_commands[name][0].empty? # See if any more of these commands are queued
|
161
|
+
@named_commands.delete(name) # Delete if there are not
|
162
|
+
else
|
163
|
+
@named_commands[name][1] = nil # Reset if there are
|
164
|
+
end
|
165
|
+
|
166
|
+
if command.nil? # decide if to continue or not
|
167
|
+
process = false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if process
|
172
|
+
if command[:delay] > 0.0
|
173
|
+
delay = @last_sent_at + command[:delay] - Time.now.to_f
|
174
|
+
if delay > 0.0
|
175
|
+
EM.add_timer delay do
|
176
|
+
process_send(command)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
process_send(command)
|
180
|
+
end
|
181
|
+
else
|
182
|
+
process_send(command)
|
183
|
+
end
|
184
|
+
else
|
185
|
+
process_next_send
|
186
|
+
end
|
187
|
+
rescue => e
|
188
|
+
EM.defer do
|
189
|
+
AutomateEm.print_error(logger, e, {
|
190
|
+
:message => "module #{@parent.class} in device_connection.rb, base : error in send loop",
|
191
|
+
:level => Logger::ERROR
|
192
|
+
})
|
193
|
+
end
|
194
|
+
ensure
|
195
|
+
ActiveRecord::Base.clear_active_connections!
|
196
|
+
@wait_queue.pop &@wait_queue_proc
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
}
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
@wait_queue.push(nil) # Don't start paused
|
205
|
+
@wait_queue.pop &@wait_queue_proc
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def process_send(command) # this is on the reactor thread
|
210
|
+
begin
|
211
|
+
if @connection.nil?
|
212
|
+
@connection = EventMachine::HttpRequest.new(@uri, @config)
|
213
|
+
#
|
214
|
+
# TODO:: allow for a block to be passed in too
|
215
|
+
#
|
216
|
+
if @parent.respond_to?(:use_middleware)
|
217
|
+
@parent.use_middleware(@connection)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# if command[:custom_client].nil?
|
222
|
+
http = @connection.__send__(command[:verb], command)
|
223
|
+
=begin else
|
224
|
+
http = @connection.__send__(command[:verb], command) do |*args|
|
225
|
+
begin
|
226
|
+
command[:custom_client].call *args
|
227
|
+
rescue => e
|
228
|
+
#
|
229
|
+
# Save the thread in case of bad data in that send
|
230
|
+
#
|
231
|
+
EM.defer do
|
232
|
+
AutomateEm.print_error(logger, e, {
|
233
|
+
:message => "module #{@parent.class} in device_connection.rb, process_send : possible bad data",
|
234
|
+
:level => Logger::ERROR
|
235
|
+
})
|
236
|
+
end
|
237
|
+
|
238
|
+
process_next_send if command[:wait]
|
239
|
+
|
240
|
+
raise e # continue propagation
|
241
|
+
end
|
242
|
+
=end end
|
243
|
+
# end
|
244
|
+
|
245
|
+
@last_sent_at = Time.now.to_f
|
246
|
+
|
247
|
+
if command[:stream]
|
248
|
+
http.stream { |chunk|
|
249
|
+
EM.defer {
|
250
|
+
@task_queue.push lambda {
|
251
|
+
if command[:callback].present?
|
252
|
+
command[:callback].call(chunk, command)
|
253
|
+
elsif @parent.respond_to?(:received)
|
254
|
+
@parent.received(chunk, command)
|
255
|
+
end
|
256
|
+
}
|
257
|
+
}
|
258
|
+
}
|
259
|
+
http.callback {
|
260
|
+
#
|
261
|
+
# streaming has finished
|
262
|
+
#
|
263
|
+
if logger.debug?
|
264
|
+
EM.defer do
|
265
|
+
logger.debug "Stream closed by remote"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
on_stream_close(http, command)
|
269
|
+
if command[:wait]
|
270
|
+
process_next_send
|
271
|
+
end
|
272
|
+
}
|
273
|
+
else
|
274
|
+
http.callback {
|
275
|
+
process_response(http, command)
|
276
|
+
}
|
277
|
+
end
|
278
|
+
|
279
|
+
if command[:headers].present?
|
280
|
+
http.headers { |hash|
|
281
|
+
EM.defer {
|
282
|
+
@task_queue.push lambda {
|
283
|
+
command[:headers].call(hash)
|
284
|
+
}
|
285
|
+
}
|
286
|
+
}
|
287
|
+
end
|
288
|
+
|
289
|
+
if command[:wait]
|
290
|
+
http.errback do
|
291
|
+
@connection = nil
|
292
|
+
|
293
|
+
if !command[:stream]
|
294
|
+
process_result(:failed, command)
|
295
|
+
|
296
|
+
EM.defer do
|
297
|
+
logger.info "module #{@parent.class} error: #{http.error}"
|
298
|
+
logger.info "A response was not received for the command: #{command[:path]}"
|
299
|
+
end
|
300
|
+
else
|
301
|
+
if logger.debug?
|
302
|
+
EM.defer do
|
303
|
+
logger.debug "Stream connection dropped"
|
304
|
+
end
|
305
|
+
end
|
306
|
+
on_stream_close(http, command)
|
307
|
+
process_next_send
|
308
|
+
end
|
309
|
+
end
|
310
|
+
elsif command[:stream]
|
311
|
+
http.errback do
|
312
|
+
@connection = nil
|
313
|
+
if logger.debug?
|
314
|
+
EM.defer do
|
315
|
+
logger.debug "Stream connection dropped"
|
316
|
+
end
|
317
|
+
end
|
318
|
+
on_stream_close(http, command)
|
319
|
+
end
|
320
|
+
process_next_send
|
321
|
+
else
|
322
|
+
http.errback do
|
323
|
+
@connection = nil
|
324
|
+
end
|
325
|
+
process_next_send
|
326
|
+
end
|
327
|
+
rescue => e
|
328
|
+
#
|
329
|
+
# Save the thread in case of bad data in that send
|
330
|
+
#
|
331
|
+
EM.defer do
|
332
|
+
AutomateEm.print_error(logger, e, {
|
333
|
+
:message => "module #{@parent.class} in device_connection.rb, process_send : possible bad data",
|
334
|
+
:level => Logger::ERROR
|
335
|
+
})
|
336
|
+
end
|
337
|
+
|
338
|
+
process_next_send
|
339
|
+
ensure
|
340
|
+
@connection = nil unless command[:keepalive]
|
341
|
+
ActiveRecord::Base.clear_active_connections!
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def process_next_send
|
346
|
+
EM.next_tick do
|
347
|
+
@wait_queue.push(nil) # Allows next response to process
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
def on_stream_close(http, command)
|
352
|
+
if command[:stream_closed].present?
|
353
|
+
EM.defer {
|
354
|
+
begin
|
355
|
+
command[:stream_closed].call(http, command)
|
356
|
+
rescue => e
|
357
|
+
#
|
358
|
+
# save from bad user code (don't want to deplete thread pool)
|
359
|
+
# This error should be logged in some consistent manner
|
360
|
+
#
|
361
|
+
AutomateEm.print_error(logger, e, {
|
362
|
+
:message => "module #{@parent.class} error whilst calling: stream closed",
|
363
|
+
:level => Logger::ERROR
|
364
|
+
})
|
365
|
+
ensure
|
366
|
+
ActiveRecord::Base.clear_active_connections!
|
367
|
+
end
|
368
|
+
}
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
|
373
|
+
#
|
374
|
+
# Caled from recieve
|
375
|
+
#
|
376
|
+
def process_response(response, command)
|
377
|
+
EM.defer do
|
378
|
+
@received_lock.synchronize { # This lock protects the send queue lock when we are emiting status
|
379
|
+
@send_monitor.mon_synchronize {
|
380
|
+
do_process_response(response, command)
|
381
|
+
}
|
382
|
+
}
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def do_process_response(response, command)
|
387
|
+
return if @shutting_down.value
|
388
|
+
|
389
|
+
result = :abort
|
390
|
+
begin
|
391
|
+
@parent.mark_emit_start(command[:emit]) if command[:emit].present?
|
392
|
+
|
393
|
+
if command[:callback].present?
|
394
|
+
result = command[:callback].call(response, command)
|
395
|
+
elsif @parent.respond_to?(:received)
|
396
|
+
result = @parent.received(response, command)
|
397
|
+
else
|
398
|
+
result = true
|
399
|
+
end
|
400
|
+
rescue => e
|
401
|
+
#
|
402
|
+
# save from bad user code (don't want to deplete thread pool)
|
403
|
+
# This error should be logged in some consistent manner
|
404
|
+
#
|
405
|
+
AutomateEm.print_error(logger, e, {
|
406
|
+
:message => "module #{@parent.class} error whilst calling: received",
|
407
|
+
:level => Logger::ERROR
|
408
|
+
})
|
409
|
+
ensure
|
410
|
+
@parent.mark_emit_end if command[:emit].present?
|
411
|
+
ActiveRecord::Base.clear_active_connections!
|
412
|
+
end
|
413
|
+
|
414
|
+
if command[:wait]
|
415
|
+
EM.schedule do
|
416
|
+
process_result(result, command)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
|
422
|
+
def process_result(result, command)
|
423
|
+
if [false, :failed].include?(result) && command[:retries] > 0 # assume command failed, we need to retry
|
424
|
+
command[:retries] -= 1
|
425
|
+
@send_queue.push(command, command[:priority] - @config[:priority_bonus])
|
426
|
+
end
|
427
|
+
|
428
|
+
#else result == :abort || result == :success || result == true || waits and retries exceeded
|
429
|
+
|
430
|
+
if command[:delay_on_recieve] > 0.0
|
431
|
+
delay_for = (@last_recieve_at + command[:delay_on_recieve] - Time.now.to_f)
|
432
|
+
|
433
|
+
if delay_for > 0.0
|
434
|
+
EM.add_timer delay_for do
|
435
|
+
process_next_send
|
436
|
+
end
|
437
|
+
else
|
438
|
+
process_next_send
|
439
|
+
end
|
440
|
+
else
|
441
|
+
process_next_send
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
|
446
|
+
|
447
|
+
#
|
448
|
+
# ----------------------------------------------------------------
|
449
|
+
# Everything below here is called from a deferred thread
|
450
|
+
#
|
451
|
+
#
|
452
|
+
def logger
|
453
|
+
@parent.logger
|
454
|
+
end
|
455
|
+
|
456
|
+
def received_lock
|
457
|
+
@send_monitor # for monitor use
|
458
|
+
end
|
459
|
+
|
460
|
+
|
461
|
+
#
|
462
|
+
# Processes sends in strict order
|
463
|
+
#
|
464
|
+
def do_send_request(path, options = {}, *args, &block)
|
465
|
+
|
466
|
+
begin
|
467
|
+
@status_lock.synchronize {
|
468
|
+
options = @default_request_options.merge(options)
|
469
|
+
}
|
470
|
+
options[:path] = path unless path.nil?
|
471
|
+
options[:retries] = 0 if options[:wait] == false
|
472
|
+
|
473
|
+
if options[:callback].nil? && (args.length > 0 || block.present?)
|
474
|
+
options[:callback] = args[0] unless args.empty? || args[0].class != Proc
|
475
|
+
options[:callback] = block unless block.nil?
|
476
|
+
end
|
477
|
+
|
478
|
+
if options[:name].present?
|
479
|
+
options[:name] = options[:name].to_sym
|
480
|
+
end
|
481
|
+
rescue => e
|
482
|
+
AutomateEm.print_error(logger, e, {
|
483
|
+
:message => "module #{@parent.class} in device_connection.rb, send : possible bad data or options hash",
|
484
|
+
:level => Logger::ERROR
|
485
|
+
})
|
486
|
+
|
487
|
+
return true
|
488
|
+
end
|
489
|
+
|
490
|
+
|
491
|
+
#
|
492
|
+
# Use a monitor here to allow for re-entrant locking
|
493
|
+
# This allows for a priority queue and we guarentee order of operations
|
494
|
+
#
|
495
|
+
bonus = false
|
496
|
+
begin
|
497
|
+
@send_monitor.mon_exit
|
498
|
+
@send_monitor.mon_enter
|
499
|
+
bonus = true
|
500
|
+
rescue
|
501
|
+
end
|
502
|
+
|
503
|
+
EM.schedule do
|
504
|
+
if bonus
|
505
|
+
options[:priority] -= @config[:priority_bonus]
|
506
|
+
end
|
507
|
+
|
508
|
+
add = true
|
509
|
+
if options[:name].present?
|
510
|
+
name = options[:name]
|
511
|
+
if @named_commands[name].nil?
|
512
|
+
@named_commands[name] = [[options[:priority]], options] #TODO:: we need to deal with the old commands emit values!
|
513
|
+
elsif @named_commands[name][0][-1] > options[:priority]
|
514
|
+
@named_commands[name][0].push(options[:priority])
|
515
|
+
@named_commands[name][1] = options #TODO:: we need to deal with the old commands emit values!
|
516
|
+
else
|
517
|
+
@named_commands[name][1] = options #TODO:: we need to deal with the old commands emit values!
|
518
|
+
add = false
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
@send_queue.push(options, options[:priority]) if add
|
523
|
+
end
|
524
|
+
|
525
|
+
return false
|
526
|
+
rescue => e
|
527
|
+
#
|
528
|
+
# Save from a fatal error
|
529
|
+
#
|
530
|
+
AutomateEm.print_error(logger, e, {
|
531
|
+
:message => "module #{@parent.class} in device_connection.rb, send : something went terribly wrong to get here",
|
532
|
+
:level => Logger::ERROR
|
533
|
+
})
|
534
|
+
return true
|
535
|
+
end
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
def default_request_options= (options)
|
540
|
+
@status_lock.synchronize {
|
541
|
+
@default_request_options.merge!(options)
|
542
|
+
}
|
543
|
+
end
|
544
|
+
|
545
|
+
def config= (options)
|
546
|
+
EM.schedule do
|
547
|
+
@config.merge!(options)
|
548
|
+
@connection = nil
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
|
553
|
+
|
554
|
+
def shutdown(system)
|
555
|
+
if @parent.leave_system(system) == 0
|
556
|
+
@shutting_down.value = true
|
557
|
+
@wait_queue.push(:shutdown)
|
558
|
+
@send_queue.push(:shutdown, -32768)
|
559
|
+
@task_queue.push(nil)
|
560
|
+
|
561
|
+
EM.defer do
|
562
|
+
begin
|
563
|
+
if @parent.respond_to?(:on_unload)
|
564
|
+
@task_lock.synchronize {
|
565
|
+
@parent.on_unload
|
566
|
+
}
|
567
|
+
end
|
568
|
+
rescue => e
|
569
|
+
#
|
570
|
+
# save from bad user code (don't want to deplete thread pool)
|
571
|
+
#
|
572
|
+
AutomateEm.print_error(logger, e, {
|
573
|
+
:message => "module #{@parent.class} error whilst calling: on_unload on shutdown",
|
574
|
+
:level => Logger::ERROR
|
575
|
+
})
|
576
|
+
ensure
|
577
|
+
@parent.clear_active_timers
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
end
|
584
|
+
end
|