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 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
@@ -8,7 +8,7 @@ desc 'Generate gemspec'
8
8
  task 'gem:spec' do
9
9
  Gemgem.spec = Gemgem.create do |s|
10
10
  s.name = 'sync-defer'
11
- s.version = '0.9.1'
11
+ s.version = '0.9.2'
12
12
 
13
13
  %w[].each{ |g| s.add_runtime_dependency(g) }
14
14
  end
@@ -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
- self.result = func.call
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
- values[index] = func.call
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
- EventMachine.defer(lambda{ func.call },
20
- lambda{ |result| fiber.resume(result)})
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{ func.call },
39
+ lambda{
40
+ begin
41
+ func.call
42
+ rescue Exception => e
43
+ exception = e
44
+ end
45
+ },
28
46
  lambda{ |result|
29
- results[index] = result
30
- fiber.resume(results.sort.map(&:last)) if results.size == funcs.size
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
@@ -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."
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "sync-defer"
5
- s.version = "0.9.1"
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-02-25"
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.17"
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
 
@@ -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.1
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-02-25 00:00:00.000000000 Z
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.17
56
+ rubygems_version: 1.8.19
57
57
  signing_key:
58
58
  specification_version: 3
59
59
  summary: Synchronous deferred operations with fibers (coroutines)