em-synchrony 1.0.2 → 1.0.3
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/README.md +1 -1
- data/em-synchrony.gemspec +1 -1
- data/lib/em-synchrony.rb +36 -5
- data/lib/em-synchrony/amqp.rb +17 -5
- data/lib/em-synchrony/em-http.rb +2 -2
- data/lib/em-synchrony/mongo.rb +1 -1
- data/spec/amqp_spec.rb +1 -1
- data/spec/defer_spec.rb +40 -0
- data/spec/http_spec.rb +6 -2
- data/spec/system_spec.rb +17 -0
- metadata +6 -2
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Collection of convenience classes and primitives to help untangle evented code,
|
|
8
8
|
* Fiber aware Multi-request interface for any callback enabled clients
|
9
9
|
* Fiber aware TCPSocket replacement, powered by EventMachine
|
10
10
|
* Fiber aware Thread, Mutex, ConditionVariable clases
|
11
|
-
* Fiber aware sleep
|
11
|
+
* Fiber aware sleep, defer, system
|
12
12
|
|
13
13
|
Supported clients:
|
14
14
|
|
data/em-synchrony.gemspec
CHANGED
data/lib/em-synchrony.rb
CHANGED
@@ -18,14 +18,29 @@ require "em-synchrony/iterator" if EventMachine::VERSION > '0.12.10'
|
|
18
18
|
|
19
19
|
module EventMachine
|
20
20
|
|
21
|
-
# A convenience method for wrapping
|
21
|
+
# A convenience method for wrapping a given block within
|
22
22
|
# a Ruby Fiber such that async operations can be transparently
|
23
23
|
# paused and resumed based on IO scheduling.
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
# It detects whether EM is running or not.
|
25
|
+
def self.synchrony(blk=nil, tail=nil)
|
26
|
+
# EM already running.
|
27
|
+
if reactor_running?
|
28
|
+
if block_given?
|
29
|
+
Fiber.new { yield }.resume
|
30
|
+
else
|
31
|
+
Fiber.new { blk.call }.resume
|
32
|
+
end
|
33
|
+
tail && add_shutdown_hook(tail)
|
34
|
+
|
35
|
+
# EM not running.
|
36
|
+
else
|
37
|
+
if block_given?
|
38
|
+
run(nil, tail) { Fiber.new { yield }.resume }
|
39
|
+
else
|
40
|
+
run(Proc.new { Fiber.new { blk.call }.resume }, tail)
|
41
|
+
end
|
27
42
|
|
28
|
-
|
43
|
+
end
|
29
44
|
end
|
30
45
|
|
31
46
|
module Synchrony
|
@@ -98,6 +113,22 @@ module EventMachine
|
|
98
113
|
def self.next_tick(&blk)
|
99
114
|
EM.next_tick { Fiber.new { blk.call }.resume }
|
100
115
|
end
|
116
|
+
|
117
|
+
# Fiber-aware EM.defer
|
118
|
+
#
|
119
|
+
def self.defer op = nil, &blk
|
120
|
+
fiber = Fiber.current
|
121
|
+
EM.defer(op || blk, lambda{ |result| fiber.resume(result) })
|
122
|
+
Fiber.yield
|
123
|
+
end
|
124
|
+
|
125
|
+
# Fiber-aware EM.system
|
126
|
+
#
|
127
|
+
def self.system cmd, *args
|
128
|
+
fiber = Fiber.current
|
129
|
+
EM.system(cmd, *args){ |out, status| fiber.resume( [out, status] ) }
|
130
|
+
Fiber.yield
|
131
|
+
end
|
101
132
|
|
102
133
|
# Routes to EM::Synchrony::Keyboard
|
103
134
|
#
|
data/lib/em-synchrony/amqp.rb
CHANGED
@@ -116,9 +116,21 @@ module EventMachine
|
|
116
116
|
class Exchange < ::AMQP::Exchange
|
117
117
|
def initialize(channel, type, name, opts = {}, &block)
|
118
118
|
f = Fiber.current
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
|
120
|
+
# AMQP Exchange constructor handles certain special exchanges differently.
|
121
|
+
# The callback passed in isn't called when the response comes back
|
122
|
+
# but is called immediately on the original calling fiber. That means that
|
123
|
+
# when the sync_cb callback yields the fiber when called, it will hang and never
|
124
|
+
# be resumed. So handle these exchanges without yielding
|
125
|
+
if name == "amq.#{type}" or name.empty? or opts[:no_declare]
|
126
|
+
exchange = nil
|
127
|
+
super(channel, type, name, opts) { |ex| exchange = ex }
|
128
|
+
else
|
129
|
+
super(channel, type, name, opts, &EM::Synchrony::AMQP.sync_cb(f))
|
130
|
+
exchange, declare_ok = Fiber.yield
|
131
|
+
raise Error.new(declare_ok.to_s) unless declare_ok.is_a?(::AMQ::Protocol::Exchange::DeclareOk)
|
132
|
+
end
|
133
|
+
|
122
134
|
exchange
|
123
135
|
end
|
124
136
|
|
@@ -143,9 +155,9 @@ module EventMachine
|
|
143
155
|
end
|
144
156
|
|
145
157
|
alias :asubscribe :subscribe
|
146
|
-
def subscribe &block
|
158
|
+
def subscribe(opts = {}, &block)
|
147
159
|
Fiber.new do
|
148
|
-
asubscribe(&EM::Synchrony::AMQP.sync_cb(Fiber.current))
|
160
|
+
asubscribe(opts, &EM::Synchrony::AMQP.sync_cb(Fiber.current))
|
149
161
|
loop { block.call(Fiber.yield) }
|
150
162
|
end.resume
|
151
163
|
end
|
data/lib/em-synchrony/em-http.rb
CHANGED
@@ -6,7 +6,7 @@ end
|
|
6
6
|
|
7
7
|
module EventMachine
|
8
8
|
module HTTPMethods
|
9
|
-
%w[get head post delete put].each do |type|
|
9
|
+
%w[get head post delete put patch options].each do |type|
|
10
10
|
class_eval %[
|
11
11
|
alias :a#{type} :#{type}
|
12
12
|
def #{type}(options = {}, &blk)
|
@@ -16,7 +16,7 @@ module EventMachine
|
|
16
16
|
if conn.error.nil?
|
17
17
|
conn.callback { f.resume(conn) }
|
18
18
|
conn.errback { f.resume(conn) }
|
19
|
-
|
19
|
+
|
20
20
|
Fiber.yield
|
21
21
|
else
|
22
22
|
conn
|
data/lib/em-synchrony/mongo.rb
CHANGED
data/spec/amqp_spec.rb
CHANGED
@@ -83,7 +83,7 @@ describe EM::Synchrony::AMQP do
|
|
83
83
|
nb_q1, nb_q2 = 0, 0
|
84
84
|
stop_cb = proc { EM.stop if nb_q1 + nb_q2 == 2 * nb_msg }
|
85
85
|
|
86
|
-
q1.subscribe do |meta, msg|
|
86
|
+
q1.subscribe(:ack => false) do |meta, msg|
|
87
87
|
msg.should match(/^Bonjour [0-9]+/)
|
88
88
|
nb_q1 += 1
|
89
89
|
stop_cb.call
|
data/spec/defer_spec.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec/helper/all"
|
2
|
+
|
3
|
+
describe EventMachine::Synchrony do
|
4
|
+
|
5
|
+
it "defer: simple" do
|
6
|
+
EM.synchrony do
|
7
|
+
x = 1
|
8
|
+
|
9
|
+
result = EM::Synchrony.defer do
|
10
|
+
x = 2
|
11
|
+
sleep 0.1
|
12
|
+
3
|
13
|
+
end
|
14
|
+
|
15
|
+
result.should == 3
|
16
|
+
x.should == 2
|
17
|
+
|
18
|
+
EM.stop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "defer: with lambda" do
|
23
|
+
EM.synchrony do
|
24
|
+
|
25
|
+
x = 1
|
26
|
+
|
27
|
+
op = lambda do
|
28
|
+
sleep 0.1
|
29
|
+
x += 1
|
30
|
+
3
|
31
|
+
end
|
32
|
+
|
33
|
+
EM::Synchrony.defer(op).should == 3
|
34
|
+
x.should == 2
|
35
|
+
|
36
|
+
EM.stop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/spec/http_spec.rb
CHANGED
@@ -28,9 +28,11 @@ describe EventMachine::HttpRequest do
|
|
28
28
|
order.push :head if EventMachine::HttpRequest.new(URL).head
|
29
29
|
order.push :post if EventMachine::HttpRequest.new(URL).delete
|
30
30
|
order.push :put if EventMachine::HttpRequest.new(URL).put
|
31
|
+
order.push :options if EventMachine::HttpRequest.new(URL).options
|
32
|
+
order.push :patch if EventMachine::HttpRequest.new(URL).patch
|
31
33
|
|
32
34
|
(now - start.to_f).should be_within(DELAY * order.size * 0.15).of(DELAY * order.size)
|
33
|
-
order.should == [:get, :post, :head, :post, :put]
|
35
|
+
order.should == [:get, :post, :head, :post, :put, :options, :patch]
|
34
36
|
|
35
37
|
s.stop
|
36
38
|
EventMachine.stop
|
@@ -49,10 +51,12 @@ describe EventMachine::HttpRequest do
|
|
49
51
|
multi.add :c, EventMachine::HttpRequest.new(URL).ahead
|
50
52
|
multi.add :d, EventMachine::HttpRequest.new(URL).adelete
|
51
53
|
multi.add :e, EventMachine::HttpRequest.new(URL).aput
|
54
|
+
multi.add :f, EventMachine::HttpRequest.new(URL).aoptions
|
55
|
+
multi.add :g, EventMachine::HttpRequest.new(URL).apatch
|
52
56
|
res = multi.perform
|
53
57
|
|
54
58
|
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
|
55
|
-
res.responses[:callback].size.should ==
|
59
|
+
res.responses[:callback].size.should == 7
|
56
60
|
res.responses[:errback].size.should == 0
|
57
61
|
|
58
62
|
s.stop
|
data/spec/system_spec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec/helper/all"
|
2
|
+
|
3
|
+
describe EventMachine::Synchrony do
|
4
|
+
|
5
|
+
it "system: simple" do
|
6
|
+
EM.synchrony do
|
7
|
+
out, status = EM::Synchrony.system("echo 'some'")
|
8
|
+
|
9
|
+
status.should == 0
|
10
|
+
out.should == "some\n"
|
11
|
+
|
12
|
+
EM.stop
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-synchrony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- spec/amqp_spec.rb
|
75
75
|
- spec/beanstalk_spec.rb
|
76
76
|
- spec/connection_pool_spec.rb
|
77
|
+
- spec/defer_spec.rb
|
77
78
|
- spec/em-mongo_spec.rb
|
78
79
|
- spec/fiber_iterator_spec.rb
|
79
80
|
- spec/helper/all.rb
|
@@ -91,6 +92,7 @@ files:
|
|
91
92
|
- spec/redis_spec.rb
|
92
93
|
- spec/remcached_spec.rb
|
93
94
|
- spec/synchrony_spec.rb
|
95
|
+
- spec/system_spec.rb
|
94
96
|
- spec/tcpsocket_spec.rb
|
95
97
|
- spec/thread_spec.rb
|
96
98
|
- spec/timer_spec.rb
|
@@ -123,6 +125,7 @@ test_files:
|
|
123
125
|
- spec/amqp_spec.rb
|
124
126
|
- spec/beanstalk_spec.rb
|
125
127
|
- spec/connection_pool_spec.rb
|
128
|
+
- spec/defer_spec.rb
|
126
129
|
- spec/em-mongo_spec.rb
|
127
130
|
- spec/fiber_iterator_spec.rb
|
128
131
|
- spec/helper/all.rb
|
@@ -140,6 +143,7 @@ test_files:
|
|
140
143
|
- spec/redis_spec.rb
|
141
144
|
- spec/remcached_spec.rb
|
142
145
|
- spec/synchrony_spec.rb
|
146
|
+
- spec/system_spec.rb
|
143
147
|
- spec/tcpsocket_spec.rb
|
144
148
|
- spec/thread_spec.rb
|
145
149
|
- spec/timer_spec.rb
|