sync-defer 0.9.0 → 0.9.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/CHANGES.md +9 -0
- data/Gemfile +1 -0
- data/README.md +20 -13
- data/Rakefile +1 -1
- data/lib/cool.io/sync-defer.rb +65 -17
- data/lib/eventmachine/sync-defer.rb +24 -3
- data/lib/sync-defer.rb +23 -0
- data/sync-defer.gemspec +3 -2
- data/test/test_sync-defer.rb +72 -20
- metadata +3 -2
data/CHANGES.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## sync-defer 0.9.1 -- 2012-02-25
|
4
|
+
|
5
|
+
* Added a generic interface which would pick the underneath reactor
|
6
|
+
automatically. `SyncDefer.defer{ sleep(10) }`
|
7
|
+
|
8
|
+
* Added multi-defer:
|
9
|
+
`SyncDefer.defer(lambda{ sleep(10) }, lambda{ sleep(5) })`
|
10
|
+
which return the values inside an array according to the index.
|
11
|
+
|
3
12
|
## sync-defer 0.9.0 -- 2012-02-24
|
4
13
|
|
5
14
|
* Birthday!
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -14,7 +14,8 @@ Synchronous deferred operations with fibers (coroutines)
|
|
14
14
|
|
15
15
|
## REQUIREMENTS:
|
16
16
|
|
17
|
-
Either cool.io or eventmachine
|
17
|
+
* Either cool.io or eventmachine
|
18
|
+
* Ruby 1.9+ (or if fibers could be used in Ruby 1.8)
|
18
19
|
|
19
20
|
## INSTALLATION:
|
20
21
|
|
@@ -24,26 +25,31 @@ Either cool.io or eventmachine
|
|
24
25
|
|
25
26
|
Remember to wrap a fiber around the client, and inside the client:
|
26
27
|
|
27
|
-
###
|
28
|
+
### Generic interface which would select underneath reactor automatically:
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
# Single computation:
|
31
|
+
puts(SyncDefer.defer{
|
32
|
+
sleep(10) # any CPU-bound operations
|
33
|
+
100}) # 100
|
32
34
|
puts "DONE"
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
# Multiple computations:
|
37
|
+
puts(SyncDefer.defer(lambda{
|
38
|
+
sleep(10) # any CPU-bound operations
|
39
|
+
100
|
40
|
+
},
|
41
|
+
lambda{
|
42
|
+
sleep(5) # any CPU-bound operations
|
43
|
+
50})) # [100, 50] # it would match the index
|
39
44
|
puts "DONE"
|
40
45
|
|
41
|
-
Full examples:
|
46
|
+
Full examples with reactor turned on:
|
42
47
|
|
43
48
|
### with cool.io:
|
44
49
|
|
45
50
|
Fiber.new{
|
46
|
-
Coolio::SyncDefer
|
51
|
+
# or Coolio::SyncDefer
|
52
|
+
SyncDefer.defer{ sleep(10) }
|
47
53
|
puts "DONE"
|
48
54
|
}.resume
|
49
55
|
Coolio::Loop.default.run
|
@@ -52,7 +58,8 @@ Full examples:
|
|
52
58
|
|
53
59
|
EM.run{
|
54
60
|
Fiber.new{
|
55
|
-
EM::SyncDefer
|
61
|
+
# or EM::SyncDefer
|
62
|
+
SyncDefer.defer{ sleep(10) }
|
56
63
|
puts "DONE"
|
57
64
|
EM.stop
|
58
65
|
}.resume
|
data/Rakefile
CHANGED
data/lib/cool.io/sync-defer.rb
CHANGED
@@ -2,26 +2,74 @@
|
|
2
2
|
require 'fiber'
|
3
3
|
require 'cool.io'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module Coolio::SyncDefer
|
6
|
+
module_function
|
7
|
+
def defer *args, &block
|
8
|
+
loop = args.find { |a| a.kind_of?(Coolio::Loop) }||Coolio::Loop.default
|
9
|
+
funcs = args.reject{ |a| a.kind_of?(Coolio::Loop) }
|
10
|
+
funcs << block if block_given?
|
11
|
+
if funcs.size == 1
|
12
|
+
DeferOne.new(funcs.first, loop).result
|
13
|
+
else
|
14
|
+
DeferMulti.new(funcs, loop).result
|
15
|
+
end
|
8
16
|
end
|
9
17
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
class Defer < Coolio::AsyncWatcher
|
19
|
+
attr_reader :result
|
20
|
+
def initialize loop=Coolio::Loop.default
|
21
|
+
super()
|
22
|
+
self.fiber = Fiber.current
|
23
|
+
attach(loop)
|
24
|
+
yield
|
25
|
+
Fiber.yield
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
attr_accessor :fiber
|
30
|
+
attr_writer :result
|
31
|
+
def on_signal
|
32
|
+
detach
|
33
|
+
fiber.resume(result)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class DeferOne < Defer
|
38
|
+
def initialize func=lambda{}, loop=Coolio::Loop.default
|
39
|
+
super(loop){ defer(func) }
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def defer func
|
44
|
+
Thread.new{
|
45
|
+
self.result = func.call
|
46
|
+
signal
|
47
|
+
}
|
48
|
+
end
|
21
49
|
end
|
22
50
|
|
23
|
-
|
24
|
-
|
25
|
-
|
51
|
+
class DeferMulti < Defer
|
52
|
+
def initialize funcs=[lambda{}], loop=Coolio::Loop.default
|
53
|
+
super(loop){ defer(funcs) }
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
attr_accessor :values, :target
|
58
|
+
def defer funcs
|
59
|
+
self.values = {}
|
60
|
+
self.target = funcs.size
|
61
|
+
funcs.each.with_index do |func, index|
|
62
|
+
Thread.new{
|
63
|
+
values[index] = func.call
|
64
|
+
signal
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def on_signal
|
70
|
+
return if values.size != target
|
71
|
+
self.result = values.sort.map(&:last)
|
72
|
+
super
|
73
|
+
end
|
26
74
|
end
|
27
75
|
end
|
@@ -4,10 +4,31 @@ require 'eventmachine'
|
|
4
4
|
|
5
5
|
module EventMachine::SyncDefer
|
6
6
|
module_function
|
7
|
-
def defer &block
|
7
|
+
def defer *funcs, &block
|
8
8
|
fiber = Fiber.current
|
9
|
-
|
10
|
-
|
9
|
+
funcs << block if block_given?
|
10
|
+
if funcs.size == 1
|
11
|
+
defer_one(fiber, funcs.first)
|
12
|
+
else
|
13
|
+
defer_multi(fiber, funcs)
|
14
|
+
end
|
11
15
|
Fiber.yield
|
12
16
|
end
|
17
|
+
|
18
|
+
def defer_one fiber, func
|
19
|
+
EventMachine.defer(lambda{ func.call },
|
20
|
+
lambda{ |result| fiber.resume(result)})
|
21
|
+
end
|
22
|
+
|
23
|
+
def defer_multi fiber, funcs
|
24
|
+
results = {}
|
25
|
+
funcs.each.with_index do |func, index|
|
26
|
+
EventMachine.defer(
|
27
|
+
lambda{ func.call },
|
28
|
+
lambda{ |result|
|
29
|
+
results[index] = result
|
30
|
+
fiber.resume(results.sort.map(&:last)) if results.size == funcs.size
|
31
|
+
})
|
32
|
+
end
|
33
|
+
end
|
13
34
|
end
|
data/lib/sync-defer.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'eventmachine/sync-defer'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'cool.io/sync-defer'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
|
12
|
+
module SyncDefer
|
13
|
+
module_function
|
14
|
+
def defer *args, &block
|
15
|
+
if Object.const_defined?(:EventMachine)
|
16
|
+
EventMachine::SyncDefer.defer(*args, &block)
|
17
|
+
elsif Object.const_defined?(:Coolio)
|
18
|
+
Coolio::SyncDefer.defer(*args, &block)
|
19
|
+
else
|
20
|
+
raise "No reactor found. Only cool.io and eventmachine are supported."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/sync-defer.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "sync-defer"
|
5
|
-
s.version = "0.9.
|
5
|
+
s.version = "0.9.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Lin Jen-Shin (godfat)"]
|
9
|
-
s.date = "2012-02-
|
9
|
+
s.date = "2012-02-25"
|
10
10
|
s.description = "Synchronous deferred operations with fibers (coroutines)"
|
11
11
|
s.email = ["godfat (XD) godfat.org"]
|
12
12
|
s.files = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
"Rakefile",
|
21
21
|
"lib/cool.io/sync-defer.rb",
|
22
22
|
"lib/eventmachine/sync-defer.rb",
|
23
|
+
"lib/sync-defer.rb",
|
23
24
|
"sync-defer.gemspec",
|
24
25
|
"task/.gitignore",
|
25
26
|
"task/gemgem.rb",
|
data/test/test_sync-defer.rb
CHANGED
@@ -1,18 +1,46 @@
|
|
1
1
|
|
2
2
|
require 'fiber'
|
3
3
|
require 'bacon'
|
4
|
+
require 'rr'
|
5
|
+
|
6
|
+
include RR::Adapters::RRMethods
|
7
|
+
|
8
|
+
require 'sync-defer'
|
4
9
|
|
5
10
|
begin
|
6
11
|
require 'cool.io/sync-defer'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
[Coolio::SyncDefer, SyncDefer].each do |defer|
|
13
|
+
describe defer do
|
14
|
+
before do
|
15
|
+
stub(Object).const_defined?(:EventMachine){ false }
|
16
|
+
stub(Object).const_defined?(:Coolio) { true }
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
RR.verify
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'defer_one' do
|
24
|
+
result = []
|
25
|
+
Fiber.new{
|
26
|
+
result << defer.defer{ sleep 0.1; result << 0; 1 }
|
27
|
+
result << defer.defer(lambda{ 2 })
|
28
|
+
result << 3
|
29
|
+
}.resume
|
30
|
+
Coolio::Loop.default.run
|
31
|
+
result.should.eql [0, 1, 2, 3]
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'defer_multi' do
|
35
|
+
result = []
|
36
|
+
Fiber.new{
|
37
|
+
result.concat(defer.defer(lambda{ sleep 0.1; 1 },
|
38
|
+
lambda{ result << 0; 2 }))
|
39
|
+
result << 3
|
40
|
+
}.resume
|
41
|
+
Coolio::Loop.default.run
|
42
|
+
result.should.eql [0, 1, 2, 3]
|
43
|
+
end
|
16
44
|
end
|
17
45
|
end
|
18
46
|
rescue LoadError => e
|
@@ -21,17 +49,41 @@ end
|
|
21
49
|
|
22
50
|
begin
|
23
51
|
require 'eventmachine/sync-defer'
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
52
|
+
[EventMachine::SyncDefer, SyncDefer].each do |defer|
|
53
|
+
describe defer do
|
54
|
+
before do
|
55
|
+
stub(Object).const_defined?(:EventMachine){ true }
|
56
|
+
end
|
57
|
+
|
58
|
+
after do
|
59
|
+
RR.verify
|
60
|
+
end
|
61
|
+
|
62
|
+
should 'defer_one' do
|
63
|
+
result = []
|
64
|
+
EM.run{
|
65
|
+
Fiber.new{
|
66
|
+
result << defer.defer{ sleep(0.1); result << 0; 1 }
|
67
|
+
result << defer.defer(lambda{ 2 })
|
68
|
+
result << 3
|
69
|
+
EM.stop
|
70
|
+
}.resume
|
71
|
+
}
|
72
|
+
result.inspect.should == [0, 1, 2, 3].inspect
|
73
|
+
end
|
74
|
+
|
75
|
+
should 'defer_multi' do
|
76
|
+
result = []
|
77
|
+
EM.run{
|
78
|
+
Fiber.new{
|
79
|
+
result.concat(defer.defer(lambda{ sleep(0.1); 1 },
|
80
|
+
lambda{ result << 0; 2 }))
|
81
|
+
result << 3
|
82
|
+
EM.stop
|
83
|
+
}.resume
|
84
|
+
}
|
85
|
+
result.inspect.should == [0, 1, 2, 3].inspect
|
86
|
+
end
|
35
87
|
end
|
36
88
|
end
|
37
89
|
rescue LoadError => e
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sync-defer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
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: 2012-02-
|
12
|
+
date: 2012-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Synchronous deferred operations with fibers (coroutines)
|
15
15
|
email:
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- Rakefile
|
29
29
|
- lib/cool.io/sync-defer.rb
|
30
30
|
- lib/eventmachine/sync-defer.rb
|
31
|
+
- lib/sync-defer.rb
|
31
32
|
- sync-defer.gemspec
|
32
33
|
- task/.gitignore
|
33
34
|
- task/gemgem.rb
|