sync-defer 0.9.0 → 0.9.1

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