em-synchrony 0.1.2 → 0.1.4
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 +48 -33
- data/VERSION +1 -1
- data/examples/all.rb +27 -0
- data/lib/em-synchrony.rb +16 -2
- data/lib/em-synchrony/iterator.rb +52 -0
- data/spec/beanstalk_spec.rb +6 -3
- data/spec/http_spec.rb +35 -37
- data/spec/iterator_spec.rb +68 -0
- data/spec/mysql_spec.rb +36 -42
- data/spec/remcached_spec.rb +24 -33
- metadata +7 -3
data/README.md
CHANGED
@@ -1,71 +1,86 @@
|
|
1
1
|
# EM-Synchrony
|
2
2
|
|
3
|
+
http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers
|
4
|
+
|
3
5
|
Collection of convenience classes and patches to common EventMachine clients to
|
4
6
|
make them Fiber aware and friendly. Word of warning: even though fibers have been
|
5
7
|
backported to Ruby 1.8.x, these classes assume Ruby 1.9 (if you're using fibers
|
6
|
-
in production, you should be on 1.9 anyway)
|
8
|
+
in production, you should be on 1.9 anyway)
|
7
9
|
|
8
10
|
Features:
|
9
11
|
|
10
12
|
* Fiber aware connection pool with sync/async query support
|
11
13
|
* Multi request interface which accepts any callback enabled client
|
14
|
+
* Fibered iterator to allow concurrency control & mixing of sync / async
|
12
15
|
* em-http-request: .get, etc are synchronous, while .aget, etc are async
|
13
16
|
* em-mysqlplus: .query is synchronous, while .aquery is async
|
14
17
|
* remcached: .get, etc, and .multi_* methods are synchronous
|
15
18
|
|
16
19
|
## Example with async em-http client:
|
17
20
|
|
18
|
-
EventMachine.
|
19
|
-
|
20
|
-
res = EventMachine::HttpRequest.new("http://www.postrank.com").get
|
21
|
+
EventMachine.synchrony do
|
22
|
+
res = EventMachine::HttpRequest.new("http://www.postrank.com").get
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
+
p "Look ma, no callbacks!"
|
25
|
+
p res
|
24
26
|
|
25
|
-
|
26
|
-
}.resume
|
27
|
+
EventMachine.stop
|
27
28
|
end
|
28
29
|
|
29
|
-
##
|
30
|
+
## EM Iterator & mixing sync / async code
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
EM.synchrony do
|
33
|
+
concurrency = 2
|
34
|
+
urls = ['http://url.1.com', 'http://url2.com']
|
35
|
+
|
36
|
+
# iterator will execute async blocks until completion, .each, .inject also work!
|
37
|
+
results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter|
|
38
|
+
|
39
|
+
# fire async requests, on completion advance the iterator
|
40
|
+
http = EventMachine::HttpRequest.new(url).aget
|
41
|
+
http.callback { iter.return(http) }
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
+
p results # all completed requests
|
45
|
+
|
46
|
+
EventMachine.stop
|
44
47
|
end
|
45
48
|
|
46
49
|
## Example connection pool shared by a fiber:
|
47
50
|
|
48
|
-
EventMachine.
|
49
|
-
|
51
|
+
EventMachine.synchrony do
|
50
52
|
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
|
51
53
|
EventMachine::MySQL.new(host: "localhost")
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
start = now
|
56
|
+
start = now
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
multi = EventMachine::Synchrony::Multi.new
|
59
|
+
multi.add :a, db.aquery("select sleep(1)")
|
60
|
+
multi.add :b, db.aquery("select sleep(1)")
|
61
|
+
res = multi.perform
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
p "Look ma, no callbacks, and parallel MySQL requests!"
|
64
|
+
p res
|
64
65
|
|
65
|
-
|
66
|
-
}.resume
|
66
|
+
EventMachine.stop
|
67
67
|
end
|
68
68
|
|
69
|
+
|
70
|
+
## Example with multi-request async em-http client:
|
71
|
+
|
72
|
+
EventMachine.synchrony do
|
73
|
+
multi = EventMachine::Synchrony::Multi.new
|
74
|
+
multi.add :a, EventMachine::HttpRequest.new("http://www.postrank.com").aget
|
75
|
+
multi.add :b, EventMachine::HttpRequest.new("http://www.postrank.com").apost
|
76
|
+
res = multi.perform
|
77
|
+
|
78
|
+
p "Look ma, no callbacks, and parallel HTTP requests!"
|
79
|
+
p res
|
80
|
+
|
81
|
+
EventMachine.stop
|
82
|
+
end
|
83
|
+
|
69
84
|
# License
|
70
85
|
|
71
86
|
(The MIT License)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/examples/all.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "lib/em-synchrony"
|
2
|
+
|
3
|
+
EM.synchrony do
|
4
|
+
|
5
|
+
# open 4 concurrent MySQL connections
|
6
|
+
db = EventMachine::Synchrony::ConnectionPool.new(size: 4) do
|
7
|
+
EventMachine::MySQL.new(host: "localhost")
|
8
|
+
end
|
9
|
+
|
10
|
+
# perform 4 http requests in parallel, and collect responses
|
11
|
+
multi = EventMachine::Synchrony::Multi.new
|
12
|
+
multi.add :page1, EventMachine::HttpRequest.new("http://service.com/page1").aget
|
13
|
+
multi.add :page2, EventMachine::HttpRequest.new("http://service.com/page2").aget
|
14
|
+
multi.add :page3, EventMachine::HttpRequest.new("http://service.com/page3").aget
|
15
|
+
multi.add :page4, EventMachine::HttpRequest.new("http://service.com/page4").aget
|
16
|
+
data = multi.perform.responses[:callback].values
|
17
|
+
|
18
|
+
# insert fetched HTTP data into a mysql database, using at most 2 connections at a time
|
19
|
+
# - note that we're writing async code within the callback!
|
20
|
+
EM::Synchrony::Iterator.new(data, 2).each do |page, iter|
|
21
|
+
db.aquery("INSERT INTO table (data) VALUES(#{page});")
|
22
|
+
db.callback { iter.return(http) }
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "All done! Stopping event loop."
|
26
|
+
EventMachine.stop
|
27
|
+
end
|
data/lib/em-synchrony.rb
CHANGED
@@ -5,9 +5,23 @@ require "eventmachine"
|
|
5
5
|
require "fiber"
|
6
6
|
|
7
7
|
require "em-synchrony/em-multi"
|
8
|
+
# require "em-synchrony/iterator" # iterators are not release in EM yet
|
9
|
+
require "em-synchrony/connection_pool"
|
10
|
+
|
8
11
|
require "em-synchrony/em-http"
|
9
12
|
require "em-synchrony/em-mysql"
|
10
|
-
# require "em-synchrony/em-jack"
|
11
13
|
require "em-synchrony/em-remcached"
|
12
14
|
|
13
|
-
|
15
|
+
module EventMachine
|
16
|
+
|
17
|
+
# A convenience method for wrapping EM.run body within
|
18
|
+
# a Ruby Fiber such that async operations can be transparently
|
19
|
+
# paused and resumed based on IO scheduling.
|
20
|
+
def self.synchrony(blk=nil, tail=nil, &block)
|
21
|
+
blk ||= block
|
22
|
+
context = Proc.new { Fiber.new { blk.call }.resume }
|
23
|
+
|
24
|
+
self.run(context, tail)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "em/iterator"
|
2
|
+
|
3
|
+
module EventMachine
|
4
|
+
module Synchrony
|
5
|
+
|
6
|
+
class Iterator < EM::Iterator
|
7
|
+
|
8
|
+
# synchronous iterator which will wait until all the
|
9
|
+
# jobs are done before returning. Unfortunately this
|
10
|
+
# means that you loose ability to choose concurrency
|
11
|
+
# on the fly (see iterator documentation in EM)
|
12
|
+
def each(foreach=nil, after=nil, &blk)
|
13
|
+
fiber = Fiber.current
|
14
|
+
|
15
|
+
fe = (foreach || blk)
|
16
|
+
cb = Proc.new do
|
17
|
+
after.call if after
|
18
|
+
fiber.resume
|
19
|
+
end
|
20
|
+
|
21
|
+
Fiber.yield super(fe, cb)
|
22
|
+
end
|
23
|
+
|
24
|
+
def map(&block)
|
25
|
+
fiber = Fiber.current
|
26
|
+
result = nil
|
27
|
+
|
28
|
+
after = Proc.new {|res| result = res; fiber.resume }
|
29
|
+
super(block, after)
|
30
|
+
|
31
|
+
Fiber.yield
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
def inject(obj, foreach = nil, after = nil, &block)
|
36
|
+
if foreach and after
|
37
|
+
super(obj, foreach, after)
|
38
|
+
else
|
39
|
+
fiber = Fiber.current
|
40
|
+
result = nil
|
41
|
+
|
42
|
+
after = Proc.new {|res| result = res; fiber.resume}
|
43
|
+
super(obj, block, after)
|
44
|
+
|
45
|
+
Fiber.yield
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/beanstalk_spec.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
require 'spec/helper'
|
1
|
+
require 'spec/helper/all'
|
2
2
|
|
3
3
|
DELAY = 0.25
|
4
4
|
|
5
|
+
__END__
|
5
6
|
describe EMJack do
|
6
7
|
|
7
8
|
it "should fire sequential Beanstalk requests" do
|
9
|
+
pending
|
10
|
+
|
8
11
|
EventMachine.run do
|
9
|
-
|
10
12
|
Fiber.new {
|
11
13
|
jack = EMJack::Connection.new
|
12
14
|
|
@@ -19,8 +21,9 @@ describe EMJack do
|
|
19
21
|
end
|
20
22
|
|
21
23
|
it "should fire multiple requests in parallel" do
|
24
|
+
pending
|
25
|
+
|
22
26
|
EventMachine.run do
|
23
|
-
|
24
27
|
Fiber.new {
|
25
28
|
jack = EMJack::Connection.new
|
26
29
|
|
data/spec/http_spec.rb
CHANGED
@@ -5,47 +5,45 @@ DELAY = 0.25
|
|
5
5
|
|
6
6
|
describe EventMachine::HttpRequest do
|
7
7
|
it "should fire sequential requests" do
|
8
|
-
EventMachine.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}.resume
|
8
|
+
EventMachine.synchrony do
|
9
|
+
s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo", DELAY)
|
10
|
+
|
11
|
+
start = now
|
12
|
+
order = []
|
13
|
+
order.push :get if EventMachine::HttpRequest.new(URL).get
|
14
|
+
order.push :post if EventMachine::HttpRequest.new(URL).post
|
15
|
+
order.push :head if EventMachine::HttpRequest.new(URL).head
|
16
|
+
order.push :post if EventMachine::HttpRequest.new(URL).delete
|
17
|
+
order.push :put if EventMachine::HttpRequest.new(URL).put
|
18
|
+
|
19
|
+
(now - start.to_f).should be_within(DELAY * order.size * 0.15).of(DELAY * order.size)
|
20
|
+
order.should == [:get, :post, :head, :post, :put]
|
21
|
+
|
22
|
+
s.stop
|
23
|
+
EventMachine.stop
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
28
27
|
it "should fire simultaneous requests via Multi interface" do
|
29
|
-
EventMachine.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}.resume
|
28
|
+
EventMachine.synchrony do
|
29
|
+
s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo", DELAY)
|
30
|
+
|
31
|
+
start = now
|
32
|
+
|
33
|
+
multi = EventMachine::Synchrony::Multi.new
|
34
|
+
multi.add :a, EventMachine::HttpRequest.new(URL).aget
|
35
|
+
multi.add :b, EventMachine::HttpRequest.new(URL).apost
|
36
|
+
multi.add :c, EventMachine::HttpRequest.new(URL).ahead
|
37
|
+
multi.add :d, EventMachine::HttpRequest.new(URL).adelete
|
38
|
+
multi.add :e, EventMachine::HttpRequest.new(URL).aput
|
39
|
+
res = multi.perform
|
40
|
+
|
41
|
+
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
|
42
|
+
res.responses[:callback].size.should == 5
|
43
|
+
res.responses[:errback].size.should == 0
|
44
|
+
|
45
|
+
s.stop
|
46
|
+
EventMachine.stop
|
49
47
|
end
|
50
48
|
end
|
51
49
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "spec/helper/all"
|
2
|
+
require "em-synchrony/iterator"
|
3
|
+
|
4
|
+
describe EventMachine::Synchrony::Iterator do
|
5
|
+
|
6
|
+
it "should wait until the iterator is done" do
|
7
|
+
EM.synchrony do
|
8
|
+
|
9
|
+
results = []
|
10
|
+
i = EM::Synchrony::Iterator.new(1..50, 10).each do |num, iter|
|
11
|
+
results.push num
|
12
|
+
iter.next
|
13
|
+
end
|
14
|
+
|
15
|
+
results.should == (1..50).to_a
|
16
|
+
results.size.should == 50
|
17
|
+
EventMachine.stop
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should map values within the iterator" do
|
22
|
+
EM.synchrony do
|
23
|
+
results = EM::Synchrony::Iterator.new(1..50, 10).map do |num, iter|
|
24
|
+
iter.return(num + 1)
|
25
|
+
end
|
26
|
+
|
27
|
+
results.should == (2..51).to_a
|
28
|
+
results.size.should == 50
|
29
|
+
EventMachine.stop
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should sum values within the iterator" do
|
34
|
+
EM.synchrony do
|
35
|
+
data = (1..50).to_a
|
36
|
+
res = EM::Synchrony::Iterator.new(data, 10).inject(0) do |total, num, iter|
|
37
|
+
total += num
|
38
|
+
iter.return(total)
|
39
|
+
end
|
40
|
+
|
41
|
+
res.should == data.inject(:+)
|
42
|
+
EventMachine.stop
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should fire async http requests in blocks of 2" do
|
47
|
+
EM.synchrony do
|
48
|
+
num_urls = 4
|
49
|
+
concurrency = 2
|
50
|
+
delay = 0.25
|
51
|
+
|
52
|
+
s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo", delay)
|
53
|
+
urls = ['http://localhost:8081/'] * num_urls
|
54
|
+
|
55
|
+
start = now
|
56
|
+
results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter|
|
57
|
+
http = EventMachine::HttpRequest.new(url).aget
|
58
|
+
http.callback { iter.return(http) }
|
59
|
+
end
|
60
|
+
|
61
|
+
results.size.should == 4
|
62
|
+
(now - start.to_f).should be_within(delay * 0.15).of(delay * (num_urls / concurrency))
|
63
|
+
|
64
|
+
EventMachine.stop
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/spec/mysql_spec.rb
CHANGED
@@ -7,23 +7,21 @@ QUERY = "select sleep(#{DELAY})"
|
|
7
7
|
describe EventMachine::MySQL do
|
8
8
|
|
9
9
|
it "should fire sequential, synchronous requests" do
|
10
|
-
EventMachine.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
res = []
|
10
|
+
EventMachine.synchrony do
|
11
|
+
db = EventMachine::MySQL.new(host: "localhost")
|
12
|
+
start = now
|
13
|
+
res = []
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
res.push db.query(QUERY)
|
16
|
+
res.push db.query(QUERY)
|
17
|
+
(now - start.to_f).should be_within(DELAY * res.size * 0.15).of(DELAY * res.size)
|
19
18
|
|
20
|
-
|
21
|
-
}.resume
|
19
|
+
EventMachine.stop
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
23
|
it "should have accept a callback, errback on async queries" do
|
26
|
-
EventMachine.
|
24
|
+
EventMachine.synchrony do
|
27
25
|
db = EventMachine::MySQL.new(host: "localhost")
|
28
26
|
|
29
27
|
res = db.aquery(QUERY)
|
@@ -36,58 +34,54 @@ describe EventMachine::MySQL do
|
|
36
34
|
end
|
37
35
|
|
38
36
|
it "should fire simultaneous requests via Multi interface" do
|
39
|
-
EventMachine.
|
37
|
+
EventMachine.synchrony do
|
40
38
|
|
41
39
|
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
|
42
40
|
EventMachine::MySQL.new(host: "localhost")
|
43
41
|
end
|
44
42
|
|
45
|
-
|
46
|
-
start = now
|
43
|
+
start = now
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
multi = EventMachine::Synchrony::Multi.new
|
46
|
+
multi.add :a, db.aquery(QUERY)
|
47
|
+
multi.add :b, db.aquery(QUERY)
|
48
|
+
res = multi.perform
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
|
51
|
+
res.responses[:callback].size.should == 2
|
52
|
+
res.responses[:errback].size.should == 0
|
56
53
|
|
57
|
-
|
58
|
-
}.resume
|
54
|
+
EventMachine.stop
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
62
58
|
it "should fire sequential and simultaneous MySQL requests" do
|
63
|
-
EventMachine.
|
59
|
+
EventMachine.synchrony do
|
64
60
|
db = EventMachine::Synchrony::ConnectionPool.new(size: 3) do
|
65
61
|
EventMachine::MySQL.new(host: "localhost")
|
66
62
|
end
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
res = []
|
64
|
+
start = now
|
65
|
+
res = []
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
res.push db.query(QUERY)
|
68
|
+
res.push db.query(QUERY)
|
69
|
+
(now - start.to_f).should be_within(DELAY * res.size * 0.15).of(DELAY * res.size)
|
75
70
|
|
76
|
-
|
71
|
+
start = now
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
multi = EventMachine::Synchrony::Multi.new
|
74
|
+
multi.add :a, db.aquery(QUERY)
|
75
|
+
multi.add :b, db.aquery(QUERY)
|
76
|
+
multi.add :c, db.aquery(QUERY)
|
77
|
+
res = multi.perform
|
83
78
|
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
(now - start.to_f).should be_within(DELAY * 0.15).of(DELAY)
|
80
|
+
res.responses[:callback].size.should == 3
|
81
|
+
res.responses[:errback].size.should == 0
|
87
82
|
|
88
|
-
|
89
|
-
}.resume
|
83
|
+
EventMachine.stop
|
90
84
|
end
|
91
85
|
end
|
92
86
|
|
93
|
-
end
|
87
|
+
end
|
data/spec/remcached_spec.rb
CHANGED
@@ -4,47 +4,38 @@ require "remcached"
|
|
4
4
|
describe Memcached do
|
5
5
|
|
6
6
|
it "should yield until connection is ready" do
|
7
|
-
EventMachine.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
EventMachine.stop
|
12
|
-
}.resume
|
7
|
+
EventMachine.synchrony do
|
8
|
+
Memcached.connect %w(localhost)
|
9
|
+
Memcached.usable?.should be_true
|
10
|
+
EventMachine.stop
|
13
11
|
end
|
14
12
|
end
|
15
13
|
|
16
14
|
it "should fire sequential memcached requests" do
|
17
|
-
EventMachine.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
EventMachine.stop
|
30
|
-
}.resume
|
15
|
+
EventMachine.synchrony do
|
16
|
+
|
17
|
+
Memcached.connect %w(localhost)
|
18
|
+
Memcached.get(key: 'hai') do |res|
|
19
|
+
res[:value].should match('Not found')
|
20
|
+
end
|
21
|
+
|
22
|
+
Memcached.set(key: 'hai', value: 'win')
|
23
|
+
Memcached.add(key: 'count')
|
24
|
+
Memcached.delete(key: 'hai')
|
25
|
+
|
26
|
+
EventMachine.stop
|
31
27
|
end
|
32
28
|
end
|
33
|
-
|
29
|
+
|
34
30
|
it "should fire multi memcached requests" do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
Memcached.multi_get([{:key => 'foo'},{:key => 'bar'}, {:key => 'test'}]) do |res|
|
43
|
-
p res
|
44
|
-
end
|
45
|
-
|
31
|
+
EventMachine.synchrony do
|
32
|
+
pending "patch mult-get"
|
33
|
+
|
34
|
+
Memcached.connect %w(localhost)
|
35
|
+
Memcached.multi_get([{:key => 'foo'},{:key => 'bar'}, {:key => 'test'}]) do |res|
|
36
|
+
# TODO
|
46
37
|
EventMachine.stop
|
47
|
-
|
38
|
+
end
|
48
39
|
end
|
49
40
|
end
|
50
41
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 4
|
9
|
+
version: 0.1.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ilya Grigorik
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-22 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -50,12 +50,14 @@ files:
|
|
50
50
|
- lib/em-synchrony/em-multi.rb
|
51
51
|
- lib/em-synchrony/em-mysql.rb
|
52
52
|
- lib/em-synchrony/em-remcached.rb
|
53
|
+
- lib/em-synchrony/iterator.rb
|
53
54
|
- spec/beanstalk_spec.rb
|
54
55
|
- spec/connection_pool_spec.rb
|
55
56
|
- spec/helper/all.rb
|
56
57
|
- spec/helper/stub-http-server.rb
|
57
58
|
- spec/helper/tolerance_matcher.rb
|
58
59
|
- spec/http_spec.rb
|
60
|
+
- spec/iterator_spec.rb
|
59
61
|
- spec/mysql_spec.rb
|
60
62
|
- spec/remcached_spec.rb
|
61
63
|
has_rdoc: true
|
@@ -96,5 +98,7 @@ test_files:
|
|
96
98
|
- spec/helper/stub-http-server.rb
|
97
99
|
- spec/helper/tolerance_matcher.rb
|
98
100
|
- spec/http_spec.rb
|
101
|
+
- spec/iterator_spec.rb
|
99
102
|
- spec/mysql_spec.rb
|
100
103
|
- spec/remcached_spec.rb
|
104
|
+
- examples/all.rb
|