sync-defer 0.9.1 → 0.9.2
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 +7 -0
- data/README.md +24 -0
- data/Rakefile +1 -1
- data/lib/cool.io/sync-defer.rb +19 -5
- data/lib/eventmachine/sync-defer.rb +30 -7
- data/lib/sync-defer.rb +3 -2
- data/sync-defer.gemspec +3 -3
- data/test/test_sync-defer.rb +52 -0
- metadata +3 -3
data/CHANGES.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## sync-defer 0.9.2 -- 2012-03-20
|
4
|
+
|
5
|
+
* Properly select the reactor.
|
6
|
+
|
7
|
+
* Make it exception aware. If there's an exception raised in the
|
8
|
+
computation, sync-defer would resume back and raise that exception.
|
9
|
+
|
3
10
|
## sync-defer 0.9.1 -- 2012-02-25
|
4
11
|
|
5
12
|
* Added a generic interface which would pick the underneath reactor
|
data/README.md
CHANGED
@@ -27,6 +27,7 @@ Remember to wrap a fiber around the client, and inside the client:
|
|
27
27
|
|
28
28
|
### Generic interface which would select underneath reactor automatically:
|
29
29
|
|
30
|
+
``` ruby
|
30
31
|
# Single computation:
|
31
32
|
puts(SyncDefer.defer{
|
32
33
|
sleep(10) # any CPU-bound operations
|
@@ -42,20 +43,27 @@ Remember to wrap a fiber around the client, and inside the client:
|
|
42
43
|
sleep(5) # any CPU-bound operations
|
43
44
|
50})) # [100, 50] # it would match the index
|
44
45
|
puts "DONE"
|
46
|
+
```
|
45
47
|
|
46
48
|
Full examples with reactor turned on:
|
47
49
|
|
48
50
|
### with cool.io:
|
49
51
|
|
52
|
+
``` ruby
|
53
|
+
# only for adding at least one watcher in the loop
|
54
|
+
Coolio::TimerWatcher.new(1).attach(Coolio::Loop.default).on_timer{detach}
|
55
|
+
|
50
56
|
Fiber.new{
|
51
57
|
# or Coolio::SyncDefer
|
52
58
|
SyncDefer.defer{ sleep(10) }
|
53
59
|
puts "DONE"
|
54
60
|
}.resume
|
55
61
|
Coolio::Loop.default.run
|
62
|
+
```
|
56
63
|
|
57
64
|
### with eventmachine:
|
58
65
|
|
66
|
+
``` ruby
|
59
67
|
EM.run{
|
60
68
|
Fiber.new{
|
61
69
|
# or EM::SyncDefer
|
@@ -64,6 +72,22 @@ Full examples with reactor turned on:
|
|
64
72
|
EM.stop
|
65
73
|
}.resume
|
66
74
|
}
|
75
|
+
```
|
76
|
+
|
77
|
+
### No problems with exceptions, use them as normal:
|
78
|
+
|
79
|
+
``` ruby
|
80
|
+
EM.run{
|
81
|
+
Fiber.new{
|
82
|
+
begin
|
83
|
+
SyncDefer.defer{ raise "BOOM" }
|
84
|
+
rescue => e
|
85
|
+
p e
|
86
|
+
end
|
87
|
+
EM.stop
|
88
|
+
}.resume
|
89
|
+
}
|
90
|
+
```
|
67
91
|
|
68
92
|
## CONTRIBUTORS:
|
69
93
|
|
data/Rakefile
CHANGED
data/lib/cool.io/sync-defer.rb
CHANGED
@@ -22,15 +22,20 @@ module Coolio::SyncDefer
|
|
22
22
|
self.fiber = Fiber.current
|
23
23
|
attach(loop)
|
24
24
|
yield
|
25
|
-
Fiber.yield
|
25
|
+
result, exception = Fiber.yield
|
26
|
+
if exception
|
27
|
+
raise exception
|
28
|
+
else
|
29
|
+
result
|
30
|
+
end
|
26
31
|
end
|
27
32
|
|
28
33
|
protected
|
29
|
-
attr_accessor :fiber
|
34
|
+
attr_accessor :fiber, :exception
|
30
35
|
attr_writer :result
|
31
36
|
def on_signal
|
32
37
|
detach
|
33
|
-
fiber.resume(result)
|
38
|
+
fiber.resume(result, exception)
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
@@ -42,7 +47,11 @@ module Coolio::SyncDefer
|
|
42
47
|
protected
|
43
48
|
def defer func
|
44
49
|
Thread.new{
|
45
|
-
|
50
|
+
begin
|
51
|
+
self.result = func.call
|
52
|
+
rescue Exception => e
|
53
|
+
self.exception = e
|
54
|
+
end
|
46
55
|
signal
|
47
56
|
}
|
48
57
|
end
|
@@ -60,13 +69,18 @@ module Coolio::SyncDefer
|
|
60
69
|
self.target = funcs.size
|
61
70
|
funcs.each.with_index do |func, index|
|
62
71
|
Thread.new{
|
63
|
-
|
72
|
+
begin
|
73
|
+
values[index] = func.call
|
74
|
+
rescue Exception => e
|
75
|
+
self.exception = e
|
76
|
+
end
|
64
77
|
signal
|
65
78
|
}
|
66
79
|
end
|
67
80
|
end
|
68
81
|
|
69
82
|
def on_signal
|
83
|
+
return super if exception
|
70
84
|
return if values.size != target
|
71
85
|
self.result = values.sort.map(&:last)
|
72
86
|
super
|
@@ -12,22 +12,45 @@ module EventMachine::SyncDefer
|
|
12
12
|
else
|
13
13
|
defer_multi(fiber, funcs)
|
14
14
|
end
|
15
|
-
Fiber.yield
|
15
|
+
result, exception = Fiber.yield
|
16
|
+
if exception
|
17
|
+
raise exception
|
18
|
+
else
|
19
|
+
result
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
def defer_one fiber, func
|
19
|
-
|
20
|
-
|
24
|
+
exception = nil
|
25
|
+
EventMachine.defer(lambda{
|
26
|
+
begin
|
27
|
+
func.call
|
28
|
+
rescue Exception => e
|
29
|
+
exception = e
|
30
|
+
end
|
31
|
+
},
|
32
|
+
lambda{ |result| fiber.resume(result, exception)})
|
21
33
|
end
|
22
34
|
|
23
35
|
def defer_multi fiber, funcs
|
24
|
-
results = {}
|
36
|
+
results, exception = {}, nil
|
25
37
|
funcs.each.with_index do |func, index|
|
26
38
|
EventMachine.defer(
|
27
|
-
lambda{
|
39
|
+
lambda{
|
40
|
+
begin
|
41
|
+
func.call
|
42
|
+
rescue Exception => e
|
43
|
+
exception = e
|
44
|
+
end
|
45
|
+
},
|
28
46
|
lambda{ |result|
|
29
|
-
|
30
|
-
|
47
|
+
if exception
|
48
|
+
fiber.resume(nil, exception)
|
49
|
+
else
|
50
|
+
results[index] = result
|
51
|
+
fiber.resume(results.sort.map(&:last), nil) if
|
52
|
+
results.size == funcs.size
|
53
|
+
end
|
31
54
|
})
|
32
55
|
end
|
33
56
|
end
|
data/lib/sync-defer.rb
CHANGED
@@ -12,9 +12,10 @@ end
|
|
12
12
|
module SyncDefer
|
13
13
|
module_function
|
14
14
|
def defer *args, &block
|
15
|
-
if Object.const_defined?(:EventMachine)
|
15
|
+
if Object.const_defined?(:EventMachine) && EventMachine.reactor_running?
|
16
16
|
EventMachine::SyncDefer.defer(*args, &block)
|
17
|
-
elsif Object.const_defined?(:Coolio)
|
17
|
+
elsif Object.const_defined?(:Coolio) &&
|
18
|
+
Coolio::Loop.default.has_active_watchers?
|
18
19
|
Coolio::SyncDefer.defer(*args, &block)
|
19
20
|
else
|
20
21
|
raise "No reactor found. Only cool.io and eventmachine are supported."
|
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.2"
|
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-
|
9
|
+
s.date = "2012-03-20"
|
10
10
|
s.description = "Synchronous deferred operations with fibers (coroutines)"
|
11
11
|
s.email = ["godfat (XD) godfat.org"]
|
12
12
|
s.files = [
|
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
"test/test_sync-defer.rb"]
|
28
28
|
s.homepage = "https://github.com/godfat/sync-defer"
|
29
29
|
s.require_paths = ["lib"]
|
30
|
-
s.rubygems_version = "1.8.
|
30
|
+
s.rubygems_version = "1.8.19"
|
31
31
|
s.summary = "Synchronous deferred operations with fibers (coroutines)"
|
32
32
|
s.test_files = ["test/test_sync-defer.rb"]
|
33
33
|
|
data/test/test_sync-defer.rb
CHANGED
@@ -7,6 +7,9 @@ include RR::Adapters::RRMethods
|
|
7
7
|
|
8
8
|
require 'sync-defer'
|
9
9
|
|
10
|
+
class TestException < Exception
|
11
|
+
end
|
12
|
+
|
10
13
|
begin
|
11
14
|
require 'cool.io/sync-defer'
|
12
15
|
[Coolio::SyncDefer, SyncDefer].each do |defer|
|
@@ -41,6 +44,28 @@ begin
|
|
41
44
|
Coolio::Loop.default.run
|
42
45
|
result.should.eql [0, 1, 2, 3]
|
43
46
|
end
|
47
|
+
|
48
|
+
should 'raise the exception' do
|
49
|
+
Fiber.new{
|
50
|
+
lambda{
|
51
|
+
defer.defer{ raise TestException }
|
52
|
+
}.should.raise(TestException)
|
53
|
+
}.resume
|
54
|
+
Coolio::Loop.default.run
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'one of them raise' do
|
58
|
+
Fiber.new{
|
59
|
+
lambda{
|
60
|
+
defer.defer(lambda{ raise TestException }, lambda{})
|
61
|
+
}.should.raise(TestException)
|
62
|
+
|
63
|
+
lambda{
|
64
|
+
defer.defer(lambda{}, lambda{ raise TestException })
|
65
|
+
}.should.raise(TestException)
|
66
|
+
}.resume
|
67
|
+
Coolio::Loop.default.run
|
68
|
+
end
|
44
69
|
end
|
45
70
|
end
|
46
71
|
rescue LoadError => e
|
@@ -84,6 +109,33 @@ begin
|
|
84
109
|
}
|
85
110
|
result.inspect.should == [0, 1, 2, 3].inspect
|
86
111
|
end
|
112
|
+
|
113
|
+
should 'raise the exception' do
|
114
|
+
EM.run{
|
115
|
+
Fiber.new{
|
116
|
+
lambda{
|
117
|
+
defer.defer{ raise TestException }
|
118
|
+
}.should.raise(TestException)
|
119
|
+
EM.stop
|
120
|
+
}.resume
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
should 'one of them raise' do
|
125
|
+
EM.run{
|
126
|
+
Fiber.new{
|
127
|
+
lambda{
|
128
|
+
defer.defer(lambda{ raise TestException }, lambda{})
|
129
|
+
}.should.raise(TestException)
|
130
|
+
|
131
|
+
lambda{
|
132
|
+
defer.defer(lambda{}, lambda{ raise TestException })
|
133
|
+
}.should.raise(TestException)
|
134
|
+
|
135
|
+
EM.stop
|
136
|
+
}.resume
|
137
|
+
}
|
138
|
+
end
|
87
139
|
end
|
88
140
|
end
|
89
141
|
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.2
|
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-
|
12
|
+
date: 2012-03-20 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Synchronous deferred operations with fibers (coroutines)
|
15
15
|
email:
|
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
53
|
version: '0'
|
54
54
|
requirements: []
|
55
55
|
rubyforge_project:
|
56
|
-
rubygems_version: 1.8.
|
56
|
+
rubygems_version: 1.8.19
|
57
57
|
signing_key:
|
58
58
|
specification_version: 3
|
59
59
|
summary: Synchronous deferred operations with fibers (coroutines)
|