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 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
@@ -5,6 +5,7 @@ gemspec
5
5
 
6
6
  gem 'rake'
7
7
  gem 'bacon'
8
+ gem 'rr'
8
9
 
9
10
  gem 'eventmachine'
10
11
  gem 'cool.io', :platforms => 'ruby'
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
- ### with cool.io:
28
+ ### Generic interface which would select underneath reactor automatically:
28
29
 
29
- Coolio::SyncDefer{
30
- sleep(10) # any CPU-bound operations
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
- ### with eventmachine:
35
-
36
- EventMachine::SyncDefer{
37
- sleep(10) # any CPU-bound operations
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.defer{ sleep(10) } # any CPU-bound operations
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.defer{ sleep(10) } # any CPU-bound operations
61
+ # or EM::SyncDefer
62
+ SyncDefer.defer{ sleep(10) }
56
63
  puts "DONE"
57
64
  EM.stop
58
65
  }.resume
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.0'
11
+ s.version = '0.9.1'
12
12
 
13
13
  %w[].each{ |g| s.add_runtime_dependency(g) }
14
14
  end
@@ -2,26 +2,74 @@
2
2
  require 'fiber'
3
3
  require 'cool.io'
4
4
 
5
- class Coolio::SyncDefer < Coolio::AsyncWatcher
6
- def self.defer loop=Coolio::Loop.default, &block
7
- new(loop, &block).result
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
- attr_reader :result
11
-
12
- def initialize loop=Coolio::Loop.default
13
- super()
14
- @fiber = Fiber.current
15
- attach(loop)
16
- Thread.new{
17
- @result = yield
18
- signal
19
- }
20
- Fiber.yield
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
- def on_signal
24
- detach
25
- @fiber.resume(result)
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
- EventMachine.defer(lambda{ yield },
10
- lambda{ |result| fiber.resume(result)})
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.0"
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-24"
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",
@@ -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
- describe Coolio::SyncDefer do
8
- should 'work' do
9
- result = []
10
- Fiber.new{
11
- result << Coolio::SyncDefer.defer{ sleep 0.1; result << 0; 1 }
12
- result << 2
13
- }.resume
14
- Coolio::Loop.default.run
15
- result.should.eql [0, 1, 2]
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
- describe EventMachine::SyncDefer do
25
- should 'work' do
26
- result = []
27
- EM.run{
28
- Fiber.new{
29
- result << EM::SyncDefer.defer{ sleep 0.1; result << 0; 1 }
30
- result << 2
31
- EM.stop
32
- }.resume
33
- }
34
- result.should.eql [0, 1, 2]
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.0
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-24 00:00:00.000000000 Z
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