sync-defer 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
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)