em-synchrony 0.1.4 → 0.1.5
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 +58 -48
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/em-synchrony.rb +7 -7
- data/lib/em-synchrony/em-bitly.rb +26 -0
- data/lib/em-synchrony/em-http.rb +7 -3
- data/lib/em-synchrony/em-jack.rb +7 -3
- data/lib/em-synchrony/{em-mysql.rb → em-mysqlplus.rb} +5 -1
- data/lib/em-synchrony/em-remcached.rb +10 -6
- data/spec/beanstalk_spec.rb +5 -5
- data/spec/connection_pool_spec.rb +1 -1
- data/spec/helper/all.rb +4 -0
- data/spec/{mysql_spec.rb → mysqlplus_spec.rb} +0 -0
- metadata +7 -6
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# EM-Synchrony
|
2
2
|
|
3
|
-
http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers
|
3
|
+
Blog post: [Untangling Evented Code with Ruby Fibers](http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers)
|
4
4
|
|
5
|
-
Collection of convenience classes and patches to common EventMachine clients to
|
5
|
+
Collection of convenience classes and patches to common EventMachine clients to
|
6
6
|
make them Fiber aware and friendly. Word of warning: even though fibers have been
|
7
7
|
backported to Ruby 1.8.x, these classes assume Ruby 1.9 (if you're using fibers
|
8
8
|
in production, you should be on 1.9 anyway)
|
@@ -15,72 +15,82 @@ Features:
|
|
15
15
|
* em-http-request: .get, etc are synchronous, while .aget, etc are async
|
16
16
|
* em-mysqlplus: .query is synchronous, while .aquery is async
|
17
17
|
* remcached: .get, etc, and .multi_* methods are synchronous
|
18
|
+
* bitly: synchronous api calls with EM::HttpRequest.
|
18
19
|
|
19
20
|
## Example with async em-http client:
|
21
|
+
require "em-synchrony/em-http"
|
22
|
+
EventMachine.synchrony do
|
23
|
+
res = EventMachine::HttpRequest.new("http://www.postrank.com").get
|
24
|
+
p "Look ma, no callbacks!"
|
25
|
+
p res
|
20
26
|
|
21
|
-
|
22
|
-
res = EventMachine::HttpRequest.new("http://www.postrank.com").get
|
23
|
-
|
24
|
-
p "Look ma, no callbacks!"
|
25
|
-
p res
|
26
|
-
|
27
|
-
EventMachine.stop
|
27
|
+
EventMachine.stop
|
28
28
|
end
|
29
29
|
|
30
30
|
## EM Iterator & mixing sync / async code
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
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|
|
32
|
+
require "em-synchrony/em-http"
|
33
|
+
EM.synchrony do
|
34
|
+
concurrency = 2
|
35
|
+
urls = ['http://url.1.com', 'http://url2.com']
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
http.callback { iter.return(http) }
|
42
|
-
end
|
37
|
+
# iterator will execute async blocks until completion, .each, .inject also work!
|
38
|
+
results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter|
|
43
39
|
|
44
|
-
|
40
|
+
# fire async requests, on completion advance the iterator
|
41
|
+
http = EventMachine::HttpRequest.new(url).aget
|
42
|
+
http.callback { iter.return(http) }
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
45
|
+
p results # all completed requests
|
46
|
+
EventMachine.stop
|
47
|
+
end
|
48
48
|
|
49
49
|
## Example connection pool shared by a fiber:
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
require "em-synchrony/em-mysqlplus"
|
52
|
+
EventMachine.synchrony do
|
53
|
+
db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
|
54
|
+
EventMachine::MySQL.new(host: "localhost")
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
+
multi = EventMachine::Synchrony::Multi.new
|
58
|
+
multi.add :a, db.aquery("select sleep(1)")
|
59
|
+
multi.add :b, db.aquery("select sleep(1)")
|
60
|
+
res = multi.perform
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
multi.add :b, db.aquery("select sleep(1)")
|
61
|
-
res = multi.perform
|
62
|
+
p "Look ma, no callbacks, and parallel MySQL requests!"
|
63
|
+
p res
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
+
EventMachine.stop
|
66
|
+
end
|
65
67
|
|
66
|
-
|
67
|
-
end
|
68
|
+
## Example with multi-request async em-http client:
|
68
69
|
|
70
|
+
require "em-synchrony/em-http"
|
71
|
+
EventMachine.synchrony do
|
72
|
+
multi = EventMachine::Synchrony::Multi.new
|
73
|
+
multi.add :a, EventMachine::HttpRequest.new("http://www.postrank.com").aget
|
74
|
+
multi.add :b, EventMachine::HttpRequest.new("http://www.postrank.com").apost
|
75
|
+
res = multi.perform
|
69
76
|
|
70
|
-
|
77
|
+
p "Look ma, no callbacks, and parallel HTTP requests!"
|
78
|
+
p res
|
79
|
+
|
80
|
+
EventMachine.stop
|
81
|
+
end
|
82
|
+
|
83
|
+
## Example with async Bitly client:
|
84
|
+
|
85
|
+
require "em-synchrony/em-bitly"
|
86
|
+
EM.synchrony do
|
87
|
+
bitly = Bitly.new('[INSERT_LOGIN]', '[INSERT_API_KEY]')
|
88
|
+
url = 'http://github.com/igrigorik/em-synchrony'
|
89
|
+
short = bitly.shorten(url)
|
90
|
+
|
91
|
+
p "Short #{url} => #{short.jmp_url}"
|
92
|
+
end
|
71
93
|
|
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
|
-
|
84
94
|
# License
|
85
95
|
|
86
96
|
(The MIT License)
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
data/lib/em-synchrony.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
2
|
|
3
|
-
require "rubygems"
|
4
3
|
require "eventmachine"
|
5
|
-
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "fiber"
|
7
|
+
rescue LoadError => error
|
8
|
+
raise error unless defined? Fiber
|
9
|
+
end
|
6
10
|
|
7
11
|
require "em-synchrony/em-multi"
|
8
|
-
# require "em-synchrony/iterator" # iterators are not release in EM yet
|
9
12
|
require "em-synchrony/connection_pool"
|
10
|
-
|
11
|
-
require "em-synchrony/em-http"
|
12
|
-
require "em-synchrony/em-mysql"
|
13
|
-
require "em-synchrony/em-remcached"
|
13
|
+
# require "em-synchrony/iterator" # iterators are not release in EM yet
|
14
14
|
|
15
15
|
module EventMachine
|
16
16
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require "em-synchrony/em-http"
|
3
|
+
require "bitly"
|
4
|
+
rescue LoadError => error
|
5
|
+
raise "Missing EM-Synchrony dependencies: gem install em-http-request; gem install bitly -v=0.4.0"
|
6
|
+
end
|
7
|
+
|
8
|
+
module Bitly
|
9
|
+
module Utils
|
10
|
+
def get_result(request)
|
11
|
+
http = EventMachine::HttpRequest.new(request).get(:timeout => 100)
|
12
|
+
|
13
|
+
result = if (http.response_header.status == 200)
|
14
|
+
Crack::JSON.parse(http.response)
|
15
|
+
else
|
16
|
+
{'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
|
17
|
+
end
|
18
|
+
|
19
|
+
if 'OK' == result['statusCode']
|
20
|
+
result['results']
|
21
|
+
else
|
22
|
+
raise BitlyError.new(result['errorMessage'],result['errorCode'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/em-synchrony/em-http.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require "em-http"
|
3
|
+
rescue LoadError => error
|
4
|
+
raise "Missing EM-Synchrony dependency: gem install em-http-request"
|
5
|
+
end
|
2
6
|
|
3
7
|
module EventMachine
|
4
8
|
class HttpRequest
|
@@ -12,9 +16,9 @@ module EventMachine
|
|
12
16
|
conn.callback { f.resume(conn) }
|
13
17
|
conn.errback { f.resume(conn) }
|
14
18
|
|
15
|
-
Fiber.yield
|
19
|
+
Fiber.yield
|
16
20
|
end
|
17
21
|
]
|
18
|
-
end
|
22
|
+
end
|
19
23
|
end
|
20
24
|
end
|
data/lib/em-synchrony/em-jack.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require "em-jack"
|
3
|
+
rescue LoadError => error
|
4
|
+
raise "Missing EM-Synchrony dependency: gem install em-jack"
|
5
|
+
end
|
2
6
|
|
3
7
|
# WANT: namespaced under EventMachine.. would be nice :-)
|
4
8
|
# NOTE: no need for "pooling" since Beanstalk supports pipelining
|
@@ -18,11 +22,11 @@ module EMJack
|
|
18
22
|
|
19
23
|
@used_tube = tube
|
20
24
|
@conn.send(:use, tube)
|
21
|
-
|
25
|
+
|
22
26
|
# WANT: Add conditional on add_deferrable to either accept two procs, or a single block
|
23
27
|
# .. two procs = callback, errback
|
24
28
|
add_deferrable { |r| f.resume(r) }
|
25
|
-
|
29
|
+
|
26
30
|
Fiber.yield
|
27
31
|
end
|
28
32
|
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require "remcached"
|
3
|
+
rescue LoadError => error
|
4
|
+
raise "Missing EM-Synchrony dependency: gem install remcached"
|
5
|
+
end
|
2
6
|
|
3
7
|
module Memcached
|
4
8
|
class << self
|
@@ -45,19 +49,19 @@ module Memcached
|
|
45
49
|
def amulti_#{type}(contents, &callback)
|
46
50
|
df = EventMachine::DefaultDeferrable.new
|
47
51
|
df.callback &callback
|
48
|
-
|
52
|
+
|
49
53
|
cb = Proc.new { |res| df.succeed(res) }
|
50
54
|
multi_operation Request::#{type.capitalize}, contents, &cb
|
51
|
-
|
55
|
+
|
52
56
|
df
|
53
57
|
end
|
54
|
-
|
58
|
+
|
55
59
|
def multi_#{type}(contents, &callback)
|
56
60
|
fiber = Fiber.current
|
57
|
-
|
61
|
+
|
58
62
|
df = amulti_#{type}(contents, &Proc.new { |res| fiber.resume(res) })
|
59
63
|
df.callback &callback
|
60
|
-
|
64
|
+
|
61
65
|
Fiber.yield
|
62
66
|
end
|
63
67
|
]
|
data/spec/beanstalk_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe EMJack do
|
|
7
7
|
|
8
8
|
it "should fire sequential Beanstalk requests" do
|
9
9
|
pending
|
10
|
-
|
10
|
+
|
11
11
|
EventMachine.run do
|
12
12
|
Fiber.new {
|
13
13
|
jack = EMJack::Connection.new
|
@@ -22,7 +22,7 @@ describe EMJack do
|
|
22
22
|
|
23
23
|
it "should fire multiple requests in parallel" do
|
24
24
|
pending
|
25
|
-
|
25
|
+
|
26
26
|
EventMachine.run do
|
27
27
|
Fiber.new {
|
28
28
|
jack = EMJack::Connection.new
|
@@ -31,14 +31,14 @@ describe EMJack do
|
|
31
31
|
multi.add jack.ause('mytube-1')
|
32
32
|
multi.add jack.ause('mytube-2')
|
33
33
|
res = multi.perform
|
34
|
-
|
34
|
+
|
35
35
|
res.responses.size.should == 2
|
36
36
|
p [:multi, res.responses]
|
37
|
-
|
37
|
+
|
38
38
|
EventMachine.stop
|
39
39
|
}.resume
|
40
40
|
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end
|
data/spec/helper/all.rb
CHANGED
File without changes
|
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
|
+
- 5
|
9
|
+
version: 0.1.5
|
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-
|
17
|
+
date: 2010-04-24 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -45,10 +45,11 @@ files:
|
|
45
45
|
- VERSION
|
46
46
|
- lib/em-synchrony.rb
|
47
47
|
- lib/em-synchrony/connection_pool.rb
|
48
|
+
- lib/em-synchrony/em-bitly.rb
|
48
49
|
- lib/em-synchrony/em-http.rb
|
49
50
|
- lib/em-synchrony/em-jack.rb
|
50
51
|
- lib/em-synchrony/em-multi.rb
|
51
|
-
- lib/em-synchrony/em-
|
52
|
+
- lib/em-synchrony/em-mysqlplus.rb
|
52
53
|
- lib/em-synchrony/em-remcached.rb
|
53
54
|
- lib/em-synchrony/iterator.rb
|
54
55
|
- spec/beanstalk_spec.rb
|
@@ -58,7 +59,7 @@ files:
|
|
58
59
|
- spec/helper/tolerance_matcher.rb
|
59
60
|
- spec/http_spec.rb
|
60
61
|
- spec/iterator_spec.rb
|
61
|
-
- spec/
|
62
|
+
- spec/mysqlplus_spec.rb
|
62
63
|
- spec/remcached_spec.rb
|
63
64
|
has_rdoc: true
|
64
65
|
homepage: http://github.com/igrigorik/em-synchrony
|
@@ -99,6 +100,6 @@ test_files:
|
|
99
100
|
- spec/helper/tolerance_matcher.rb
|
100
101
|
- spec/http_spec.rb
|
101
102
|
- spec/iterator_spec.rb
|
102
|
-
- spec/
|
103
|
+
- spec/mysqlplus_spec.rb
|
103
104
|
- spec/remcached_spec.rb
|
104
105
|
- examples/all.rb
|