plezi 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +2 -2
- data/bin/plezi +2 -2
- data/lib/plezi/eventmachine/em.rb +6 -3
- data/lib/plezi/eventmachine/timers.rb +1 -1
- data/lib/plezi/eventmachine/workers.rb +1 -3
- data/lib/plezi/handlers/controller_magic.rb +38 -11
- data/lib/plezi/server/websocket_client.rb +1 -0
- data/lib/plezi/server/ws_response.rb +4 -2
- data/lib/plezi/version.rb +1 -1
- data/resources/Gemfile +1 -1
- data/test/plezi_tests.rb +78 -33
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7c44156e8d07feee948374172192f5bbaafa806
|
4
|
+
data.tar.gz: a8a7badafd82d78e01a20d3ccf55e8bcc1dbd20a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54db5b96460193896c8feacf4db749ea68132b0659007b93b54633bc4e99e45689906bc666df1517aa644e2f5f573d63d4b0364a4723ddc621c13ec7eae6dd53
|
7
|
+
data.tar.gz: 1e2426a2844334deb000f49381f6dad3ee1c89feaff3feb32944ba5ec7ad03a37c44985de8a4d50bf7ab7c88479893d180ca871ee782c2e22a425359876cac3f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.8.6
|
6
|
+
|
7
|
+
**fix**: fixed an issue with the plezi helper script that prevented the script from starting the Plezi app or Plezi console.
|
8
|
+
|
9
|
+
**feature**: Unicasting allows you to target a specific Websocket connection using a unique identifier (UUID). Use the controllers `#unicast(target_uuid, mathod_name, *args) to target a specific client. Automatically uses Radis, if Radis is set up, to unicast across processes.
|
10
|
+
|
11
|
+
***
|
12
|
+
|
5
13
|
Change log v.0.8.5
|
6
14
|
|
7
15
|
**feature**: Plezi now includes a very simple Websocket Client (no support for cookies). It's used for testing the integrity of the Plezi Framework and could be used to test the Plezi apps.
|
data/README.md
CHANGED
@@ -36,13 +36,13 @@ to create a new barebones app using the Plezi framework, run from terminal:
|
|
36
36
|
That's it, now you have a ready to use basic web server (with some demo code), just run it:
|
37
37
|
|
38
38
|
$ cd appname
|
39
|
-
$ ./appname
|
39
|
+
$ ./appname # ( or: plezi s )
|
40
40
|
|
41
41
|
now go, in your browser, to: [http://localhost:3000/](http://localhost:3000/)
|
42
42
|
|
43
43
|
the default first port for the app is 3000. you can set the first port to listen to by using the `-p ` option (make sure you have permissions for the requested port):
|
44
44
|
|
45
|
-
$ ./appname
|
45
|
+
$ ./appname -p 80
|
46
46
|
|
47
47
|
you now have a smart framework app that will happily eat any gem you feed it. it responds extra well to Haml, Sass and Coffee-Script, which you can enable in it's Gemfile.
|
48
48
|
|
data/bin/plezi
CHANGED
@@ -264,10 +264,10 @@ if ARGV[0] == 'new' || ARGV[0] == 'n' || ARGV[0] == "force"
|
|
264
264
|
template.build
|
265
265
|
elsif ARGV[0] == 'server' || ARGV[0] == 'start' || ARGV[0] == 's'
|
266
266
|
ARGV.shift
|
267
|
-
load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last
|
267
|
+
load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last ) ) )
|
268
268
|
elsif ARGV[0] == 'console' || ARGV[0] == 'c'
|
269
269
|
NO_PLEZI_AUTO_START ||= true
|
270
|
-
load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last
|
270
|
+
load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) )
|
271
271
|
ARGV.clear
|
272
272
|
IRB.setup nil
|
273
273
|
IRB.conf[:MAIN_CONTEXT] = IRB::Irb.new.context
|
@@ -28,11 +28,14 @@ module Plezi
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def stop_and_wait
|
31
|
-
@
|
31
|
+
@workers.each {|w| w.stop }
|
32
|
+
@workers.each {|w| w.join }
|
33
|
+
@workers_lock.synchronize { @workers.clear }
|
32
34
|
end
|
33
35
|
|
34
36
|
def stop
|
35
|
-
@
|
37
|
+
@workers.each {|w| w.stop }
|
38
|
+
@workers_lock.synchronize { @workers.clear;}
|
36
39
|
end
|
37
40
|
|
38
41
|
def running?
|
@@ -48,9 +51,9 @@ module Plezi
|
|
48
51
|
SHUTDOWN_CALLBACKS = []
|
49
52
|
# runs the shutdown queue
|
50
53
|
def shutdown
|
51
|
-
stop_and_wait rescue false
|
52
54
|
old_timeout = io_timeout
|
53
55
|
io_timeout = 0.001
|
56
|
+
stop_and_wait rescue false
|
54
57
|
run
|
55
58
|
io_timeout = old_timeout
|
56
59
|
do_job while do_job
|
@@ -9,6 +9,7 @@ module Plezi
|
|
9
9
|
@thread = Thread.new { EventMachine.run wait until @stop }
|
10
10
|
end
|
11
11
|
def stop
|
12
|
+
@instances = -1
|
12
13
|
@stop = true
|
13
14
|
end
|
14
15
|
def join
|
@@ -27,9 +28,6 @@ module Plezi
|
|
27
28
|
@instances += 1 if @instances < 7
|
28
29
|
@primes[@instances] / 10.0
|
29
30
|
end
|
30
|
-
def self.reset_wait
|
31
|
-
@instances = -1
|
32
|
-
end
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -44,9 +44,14 @@ module Plezi
|
|
44
44
|
# the parameters used to create the host (the parameters passed to the `listen` / `add_service` call).
|
45
45
|
attr_reader :host_params
|
46
46
|
|
47
|
-
#
|
47
|
+
# Get's the websocket's unique identifier for unicast transmissions.
|
48
|
+
#
|
49
|
+
# This UUID is also used to make sure Radis broadcasts don't triger the
|
48
50
|
# boadcasting object's event.
|
49
|
-
|
51
|
+
def uuid
|
52
|
+
@uuid ||= SecureRandom.uuid
|
53
|
+
end
|
54
|
+
alias :unicast_id :uuid
|
50
55
|
|
51
56
|
# checks whether this instance accepts broadcasts (WebSocket instances).
|
52
57
|
def accepts_broadcast?
|
@@ -54,6 +59,8 @@ module Plezi
|
|
54
59
|
end
|
55
60
|
# sets the controller to refuse "broadcasts".
|
56
61
|
#
|
62
|
+
# The controller will also refuse any messages directed at it using the `unicast` method.
|
63
|
+
#
|
57
64
|
# This allows some websocket connections to isolate themselves even before they are fully disconnected.
|
58
65
|
#
|
59
66
|
# call this method once it is clear the websocket connection should be terminated.
|
@@ -253,7 +260,12 @@ module Plezi
|
|
253
260
|
def broadcast method_name, *args, &block
|
254
261
|
return false unless self.class.public_instance_methods.include?(method_name)
|
255
262
|
@uuid ||= SecureRandom.uuid
|
256
|
-
self.class.__inner_redis_broadcast(uuid, method_name, args, &block) || self.class.__inner_process_broadcast(uuid, method_name.to_sym, args, &block)
|
263
|
+
self.class.__inner_redis_broadcast(uuid, nil, method_name, args, &block) || self.class.__inner_process_broadcast(uuid, nil, method_name.to_sym, args, &block)
|
264
|
+
end
|
265
|
+
|
266
|
+
# {include:ControllerMagic::ClassMethods#unicast}
|
267
|
+
def unicast target_uuid, method_name, *args
|
268
|
+
self.class.unicast target_uuid, method_name, *args
|
257
269
|
end
|
258
270
|
|
259
271
|
# WebSockets.
|
@@ -370,9 +382,9 @@ module Plezi
|
|
370
382
|
# end
|
371
383
|
|
372
384
|
|
373
|
-
#
|
385
|
+
# Reviews the Redis connection, sets it up if it's missing and returns the Redis connection.
|
374
386
|
#
|
375
|
-
#
|
387
|
+
# A Redis connection will be automatically created if the `ENV['PL_REDIS_URL']` is set.
|
376
388
|
# for example:
|
377
389
|
# ENV['PL_REDIS_URL'] = ENV['REDISCLOUD_URL']`
|
378
390
|
# or
|
@@ -409,7 +421,7 @@ module Plezi
|
|
409
421
|
on.message do |channel, msg|
|
410
422
|
args = JSON.parse(msg)
|
411
423
|
params = args.shift
|
412
|
-
__inner_process_broadcast params['_pl_ignore_object'], params['_pl_method_broadcasted'].to_sym, args
|
424
|
+
__inner_process_broadcast params['_pl_ignore_object'], params['_pl_target_object'], params['_pl_method_broadcasted'].to_sym, args
|
413
425
|
end
|
414
426
|
end
|
415
427
|
rescue Exception => e
|
@@ -427,16 +439,16 @@ module Plezi
|
|
427
439
|
end
|
428
440
|
|
429
441
|
# broadcasts messages (methods) for this process
|
430
|
-
def __inner_process_broadcast ignore, method_name, args, &block
|
431
|
-
ObjectSpace.each_object(self) { |controller| Plezi.callback controller, method_name, *args, &block if controller.accepts_broadcast? && (!ignore || controller.uuid != ignore) }
|
442
|
+
def __inner_process_broadcast ignore, target, method_name, args, &block
|
443
|
+
ObjectSpace.each_object(self) { |controller| Plezi.callback controller, method_name, *args, &block if controller.accepts_broadcast? && (!ignore || (controller.uuid != ignore)) && (!target || (controller.uuid == target)) }
|
432
444
|
end
|
433
445
|
|
434
446
|
# broadcasts messages (methods) between all processes (using Redis).
|
435
|
-
def __inner_redis_broadcast ignore, method_name, args, &block
|
447
|
+
def __inner_redis_broadcast ignore, target, method_name, args, &block
|
436
448
|
return false unless redis_connection
|
437
449
|
raise "Radis broadcasts cannot accept blocks (no inter-process callbacks of memory sharing)!" if block
|
438
450
|
# raise "Radis broadcasts accept only one paramater, which is an optional Hash (no inter-process memory sharing)" if args.length > 1 || (args[0] && !args[0].is_a?(Hash))
|
439
|
-
args.unshift ({_pl_method_broadcasted: method_name, _pl_ignore_object: ignore})
|
451
|
+
args.unshift ({_pl_method_broadcasted: method_name, _pl_ignore_object: ignore, _pl_target_object: target})
|
440
452
|
redis_connection.publish(redis_channel_name, args.to_json )
|
441
453
|
true
|
442
454
|
end
|
@@ -456,7 +468,22 @@ module Plezi
|
|
456
468
|
# the method will be called asynchrnously for each sibling instance of this Controller class.
|
457
469
|
def broadcast method_name, *args, &block
|
458
470
|
return false unless public_instance_methods.include?(method_name)
|
459
|
-
__inner_redis_broadcast(nil, method_name, args, &block) || __inner_process_broadcast(nil, method_name.to_sym, args, &block)
|
471
|
+
__inner_redis_broadcast(nil, nil, method_name, args, &block) || __inner_process_broadcast(nil, nil, method_name.to_sym, args, &block)
|
472
|
+
end
|
473
|
+
|
474
|
+
# WebSockets.
|
475
|
+
#
|
476
|
+
# Class method.
|
477
|
+
#
|
478
|
+
# Use this to unidcast an event to specific websocket connection using it's UUID.
|
479
|
+
#
|
480
|
+
# accepts:
|
481
|
+
# target_uuid:: the target's unique UUID.
|
482
|
+
# method_name:: a Symbol with the method's name that should respond to the broadcast.
|
483
|
+
# *args:: any arguments that should be passed to the method (IF REDIS IS USED, LIMITATIONS APPLY).
|
484
|
+
def unicast target_uuid, method_name, *args
|
485
|
+
return false unless public_instance_methods.include?(method_name.to_sym)
|
486
|
+
__inner_redis_broadcast(nil, target_uuid, method_name, args) || __inner_process_broadcast(nil, target_uuid, method_name.to_sym, args)
|
460
487
|
end
|
461
488
|
|
462
489
|
# WebSockets.
|
@@ -73,10 +73,12 @@ module Plezi
|
|
73
73
|
self
|
74
74
|
end
|
75
75
|
|
76
|
+
# a closeing Proc
|
77
|
+
CLOSE_PROC = Proc.new {|c| c.send "\x88\x00"; c.close}
|
78
|
+
|
76
79
|
# sends any pending data and closes the connection.
|
77
80
|
def close
|
78
|
-
service.
|
79
|
-
service.close
|
81
|
+
service.locker.locked? ? (EventMachine.queue [service], CLOSE_PROC) : (CLOSE_PROC.call(service))
|
80
82
|
end
|
81
83
|
|
82
84
|
FRAME_SIZE_LIMIT = 131_072
|
data/lib/plezi/version.rb
CHANGED
data/resources/Gemfile
CHANGED
@@ -21,7 +21,7 @@ gem 'plezi'
|
|
21
21
|
#
|
22
22
|
# gem 'activesupport', :require => ['active_support', 'active_support/core_ext']
|
23
23
|
## or:
|
24
|
-
# gem 'activesupport', :require => ['active_support', active_support/all']
|
24
|
+
# gem 'activesupport', :require => ['active_support', 'active_support/all']
|
25
25
|
|
26
26
|
|
27
27
|
####################
|
data/test/plezi_tests.rb
CHANGED
@@ -110,8 +110,18 @@ class TestCtrl
|
|
110
110
|
#
|
111
111
|
# data is a string that contains binary or UTF8 (message dependent) data.
|
112
112
|
def on_message data
|
113
|
-
|
114
|
-
|
113
|
+
case data
|
114
|
+
when 'get uuid'
|
115
|
+
response << "uuid: #{uuid}"
|
116
|
+
when /to: ([^\s]*)/
|
117
|
+
# puts "cating target: #{data.match(/to: ([^\s]*)/)[1]}"
|
118
|
+
unicast data.match(/to: ([^\s]*)/)[1], :_push, "unicast"
|
119
|
+
# broadcast :_push, "unicast"
|
120
|
+
else
|
121
|
+
broadcast :_push, data
|
122
|
+
_push data
|
123
|
+
end
|
124
|
+
return true
|
115
125
|
end
|
116
126
|
|
117
127
|
# called when a disconnect packet has been recieved or the connection has been cut
|
@@ -129,8 +139,8 @@ module PleziTestTasks
|
|
129
139
|
module_function
|
130
140
|
|
131
141
|
|
132
|
-
RESULTS = {true => "\e[32mpassed\e[0m"}
|
133
|
-
RESULTS.default =
|
142
|
+
RESULTS = {true => "\e[32mpassed\e[0m", :waiting => "\e[32mwaiting validation\e[0m", :failed => "\e[31mFAILED!\e[0m"}
|
143
|
+
RESULTS.default = RESULTS[:failed]
|
134
144
|
|
135
145
|
def run_tests
|
136
146
|
(public_methods(false)).each {|m| method(m).call if m.to_s.match /^test_/}
|
@@ -221,44 +231,50 @@ module PleziTestTasks
|
|
221
231
|
puts " **** #url_for test FAILED TO RUN!!!"
|
222
232
|
puts e
|
223
233
|
end
|
224
|
-
def test_404
|
225
|
-
puts " * 404 not found and router continuity tests: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/get404" ).code == '404' ]}"
|
226
|
-
|
227
|
-
rescue => e
|
228
|
-
puts " **** 404 not found test FAILED TO RUN!!!"
|
229
|
-
puts e
|
230
|
-
end
|
231
|
-
def test_500
|
232
|
-
workers = Plezi::EventMachine.count_living_workers
|
233
|
-
puts " * 500 internal error test: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code == '500' ]}"
|
234
|
-
# cause 10 more exceptions to be raised... testing thread survival.
|
235
|
-
10.times { Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code }
|
236
|
-
workers_after_test = Plezi::EventMachine.count_living_workers
|
237
|
-
puts " * Worker survival test: #{RESULTS[workers_after_test == workers]} (#{workers_after_test} out of #{workers})"
|
238
|
-
|
239
|
-
rescue => e
|
240
|
-
puts " **** 500 internal error test FAILED TO RUN!!!"
|
241
|
-
puts e
|
242
|
-
end
|
243
234
|
def test_websocket
|
244
|
-
connection_test = broadcast_test = echo_test = false
|
235
|
+
connection_test = broadcast_test = echo_test = unicast_test = false
|
245
236
|
begin
|
237
|
+
ws4 = Plezi::WebsocketClient.connect_to("wss://localhost:3030") do |msg|
|
238
|
+
if msg == "unicast"
|
239
|
+
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
240
|
+
unicast_test = :failed
|
241
|
+
end
|
242
|
+
end
|
246
243
|
ws2 = Plezi::WebsocketClient.connect_to("wss://localhost:3030") do |msg|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
244
|
+
next unless @is_connected || !(@is_connected = true)
|
245
|
+
if msg == "unicast"
|
246
|
+
puts " * Websocket unicast message test: #{RESULTS[false]}"
|
247
|
+
unicast_test = :failed
|
248
|
+
next
|
249
|
+
else
|
250
|
+
puts " * Websocket broadcast message test: #{RESULTS[broadcast_test = (msg == 'echo test')]}"
|
251
|
+
go_test = false
|
252
|
+
end
|
251
253
|
end
|
254
|
+
ws3 = Plezi::WebsocketClient.connect_to("wss://localhost:3030") do |msg|
|
255
|
+
if msg.match /uuid: ([^s]*)/
|
256
|
+
ws2 << "to: #{msg.match(/^uuid: ([^s]*)/)[1]}"
|
257
|
+
puts " * Websocket UUID for unicast testing: #{msg.match(/^uuid: ([^s]*)/)[1]}"
|
258
|
+
elsif msg == "unicast"
|
259
|
+
puts " * Websocket unicast testing: #{RESULTS[:waiting]}"
|
260
|
+
unicast_test ||= true
|
261
|
+
end
|
262
|
+
end
|
263
|
+
ws3 << 'get uuid'
|
252
264
|
puts " * Websocket SSL client test: #{RESULTS[ws2 && true]}"
|
253
265
|
ws1 = Plezi::WebsocketClient.connect_to("ws://localhost:3000") do |msg|
|
254
266
|
unless @connected
|
255
267
|
puts " * Websocket connection message test: #{RESULTS[connection_test = (msg == 'connected')]}"
|
256
268
|
@connected = true
|
257
269
|
response << "echo test"
|
258
|
-
|
270
|
+
next
|
271
|
+
end
|
272
|
+
if msg == "unicast"
|
273
|
+
puts " * Websocket unicast testing: #{RESULTS[false]}"
|
274
|
+
unicast_test = :failed
|
275
|
+
next
|
259
276
|
end
|
260
277
|
puts " * Websocket echo message test: #{RESULTS[echo_test = (msg == 'echo test')]}"
|
261
|
-
response.close
|
262
278
|
end
|
263
279
|
|
264
280
|
rescue => e
|
@@ -267,16 +283,39 @@ module PleziTestTasks
|
|
267
283
|
end
|
268
284
|
remote = Plezi::WebsocketClient.connect_to("wss://echo.websocket.org/") {|msg| puts " * Extra Websocket Remote test (SSL: echo.websocket.org): #{RESULTS[msg == 'Hello websockets!']}"; response.close}
|
269
285
|
remote << "Hello websockets!"
|
270
|
-
sleep 0.
|
286
|
+
sleep 0.5
|
287
|
+
[ws1, ws2, ws3, ws4, remote].each {|ws| ws.close}
|
271
288
|
PL.on_shutdown {puts " * Websocket connection message test: #{RESULTS[connection_test]}" unless connection_test}
|
272
289
|
PL.on_shutdown {puts " * Websocket echo message test: #{RESULTS[echo_test]}" unless echo_test}
|
273
290
|
PL.on_shutdown {puts " * Websocket broadcast message test: #{RESULTS[broadcast_test]}" unless broadcast_test}
|
291
|
+
PL.on_shutdown {puts " * Websocket unicast message test: #{RESULTS[unicast_test]}"}
|
292
|
+
end
|
293
|
+
def test_404
|
294
|
+
puts " * 404 not found and router continuity tests: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/get404" ).code == '404' ]}"
|
295
|
+
|
296
|
+
rescue => e
|
297
|
+
puts " **** 404 not found test FAILED TO RUN!!!"
|
298
|
+
puts e
|
299
|
+
end
|
300
|
+
def test_500
|
301
|
+
workers = Plezi::EventMachine.count_living_workers
|
302
|
+
putc " * 500 internal error test: #{RESULTS[ Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code == '500' ]}"
|
303
|
+
# cause 10 more exceptions to be raised... testing thread survival.
|
304
|
+
10.times { putc "."; Net::HTTP.get_response(URI.parse "http://localhost:3000/fail" ).code }
|
305
|
+
putc "\n"
|
306
|
+
workers_after_test = Plezi::EventMachine.count_living_workers
|
307
|
+
puts " * Worker survival test: #{RESULTS[workers_after_test == workers]} (#{workers_after_test} out of #{workers})"
|
308
|
+
|
309
|
+
rescue => e
|
310
|
+
puts " **** 500 internal error test FAILED TO RUN!!!"
|
311
|
+
puts e
|
274
312
|
end
|
275
313
|
end
|
276
314
|
|
277
315
|
NO_PLEZI_AUTO_START = true
|
278
316
|
|
279
317
|
PL.create_logger '/dev/null'
|
318
|
+
# PL.max_threads = 4
|
280
319
|
|
281
320
|
listen port: 3000
|
282
321
|
|
@@ -298,12 +337,18 @@ puts " --- Failed tests should read: #{PleziTestTasks::RESULTS[false]}"
|
|
298
337
|
PleziTestTasks.run_tests
|
299
338
|
|
300
339
|
|
301
|
-
Plezi::EventMachine.clear_timers
|
340
|
+
# Plezi::EventMachine.clear_timers
|
302
341
|
|
303
342
|
sleep PLEZI_TEST_TIME if defined? PLEZI_TEST_TIME
|
304
343
|
|
305
344
|
Plezi::DSL.stop_services
|
306
|
-
|
345
|
+
puts "#{Plezi::EventMachine::EM_IO.count} connections awaiting shutdown."
|
346
|
+
Plezi::EventMachine.stop_connections
|
347
|
+
puts "#{Plezi::EventMachine::EM_IO.count} connections awaiting shutdown after connection close attempt."
|
348
|
+
if Plezi::EventMachine::EM_IO.count > 0
|
349
|
+
Plezi::EventMachine.forget_connections
|
350
|
+
puts "#{Plezi::EventMachine::EM_IO.count} connections awaiting shutdown after connections were forgotten."
|
351
|
+
end
|
307
352
|
Plezi::EventMachine.shutdown
|
308
353
|
|
309
354
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plezi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|