em-scenario 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,9 +7,74 @@ Names use kitchen's latin, because it's more leet then japanese words.
7
7
 
8
8
  Ruby 1.9.2 is used, it may work with ruby 1.8.x
9
9
 
10
+ Scenario use the bleeding edge version of event machine, the 1.0.0.beta3, with few informations from Google, checkout the source and build the doc yourself.
11
+ Some of this patterns are now in Event Machine, with a verbose syntax and without chainability. I'll try to don't rebuild the wheel and use it.
12
+
10
13
  Tools
11
14
  -----
12
15
 
16
+ ### Multi
17
+
18
+ Just like the Multi tool in _em-http-request_ and _em-synchrony_.
19
+ You can launch any deferrable.
20
+
21
+ ```ruby
22
+ EM.run do
23
+ m = EM::Scenario::Multi.new
24
+ stack = []
25
+ m.add(EM::Scenario::Timer.new(Random.rand(0.1)) do
26
+ stack << 1
27
+ end)
28
+ m.add(EM::Scenario::Timer.new(Random.rand(0.1)) do
29
+ stack << 2
30
+ end)
31
+ m.add(EM::Scenario::Timer.new(Random.rand(0.1)) do
32
+ stack << 3
33
+ end)
34
+ m.callback do
35
+ assert [1,2,3] == stack.sort
36
+ EM.stop
37
+ end
38
+ end
39
+ ```
40
+
41
+ ### Sequence
42
+
43
+ No stairs, just a sequence of deferrables.
44
+
45
+ ```ruby
46
+ EM.run do
47
+ stack = []
48
+ EM::Scenario::Sequence.new do
49
+ EM::Scenario::Timer.new(0.4) do
50
+ stack << 1
51
+ end
52
+ end.then do
53
+ EM::Scenario::Timer.new(0.3) do
54
+ stack << 2
55
+ end
56
+ end.then do |iter|
57
+ EM::Scenario::Timer.new(0.2) do
58
+ stack << 3
59
+ iter.return 42 #you can return values for the next step
60
+ end
61
+ end.then do |iter, n|
62
+ assert n == 42 # and retrieve it
63
+ EM::Scenario::Timer.new(0.1) do
64
+ stack << 4
65
+ end
66
+ end.then do
67
+ assert (1..4).to_a == stack
68
+ EM.stop
69
+ end
70
+ end
71
+ ```
72
+
73
+ Experimentations
74
+ ----------------
75
+
76
+ Strange and experimental tools with strange names. Most are specific and redundant iterator. Some guinea pigs could die soon.
77
+
13
78
  ### Quorum
14
79
 
15
80
  Do something when n actions are done.
@@ -0,0 +1,12 @@
1
+ module EventMachine
2
+ module Scenario
3
+
4
+ class Scenario
5
+ include EM::Deferrable
6
+
7
+ end
8
+
9
+ end
10
+ end
11
+
12
+
@@ -0,0 +1,23 @@
1
+ require "eventmachine"
2
+
3
+ module EventMachine
4
+ module Scenario
5
+
6
+ class Iterator
7
+ include EM::Deferrable
8
+
9
+ def initialize array, workers=10, &block
10
+ @datas = array
11
+ @action = block
12
+ @workers = workers
13
+ end
14
+
15
+ def finally &block
16
+ EM::Iterator.new(@datas, @workers).map(
17
+ @action, block
18
+ )
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,197 @@
1
+ require "eventmachine"
2
+ require "scenario/core"
3
+
4
+ # @see http://en.wikipedia.org/wiki/List_of_Latin_phrases
5
+
6
+ module EventMachine
7
+ module Scenario
8
+
9
+ # from the start
10
+ # Sequences of actions.
11
+ class AbInitio
12
+ include EM::Deferrable
13
+
14
+ def initialize &block
15
+ @actions = AbInitioActions.new
16
+ block.call @actions
17
+ self
18
+ end
19
+
20
+ def nextStep
21
+ if @actions.actions.length > 0
22
+ @actions.actions.pop.succeed(Proc.new { nextStep })
23
+ else
24
+ self.succeed
25
+ end
26
+ end
27
+
28
+ def finally &block
29
+ self.callback &block
30
+ @actions.actions.reverse!
31
+ self.nextStep
32
+ end
33
+ end
34
+
35
+ class AbInitioActions
36
+ attr_accessor :actions
37
+ def initialize
38
+ @actions = []
39
+ end
40
+
41
+ def then &block
42
+ d = EM::DefaultDeferrable.new
43
+ d.callback(&block)
44
+ @actions << d
45
+ self
46
+ end
47
+
48
+ end
49
+
50
+ #Trigger when a quota of actions is done
51
+ class Quorum < Scenario
52
+ include EM::Deferrable
53
+
54
+ def initialize times, &block
55
+ @times = times
56
+ @loop = block
57
+ self
58
+ end
59
+
60
+ def finally &block
61
+ self.callback(&block)
62
+ @loop.call( Proc.new {nextStep} )
63
+ end
64
+
65
+ protected
66
+ def nextStep
67
+ @times -= 1
68
+ self.succeed(self) if @times == 0
69
+ end
70
+ end
71
+
72
+ # As much as enough.
73
+ # You wont lots of parralel workers, but not too much.
74
+ class QuantumSatis
75
+ include EM::Deferrable
76
+
77
+ def initialize times, throttle=nil, &block
78
+ @opened = 0
79
+ @finished = 0
80
+ @worker = 0
81
+ @times = times
82
+ @throttle = throttle
83
+ @loop = block
84
+ @debug = false
85
+ end
86
+
87
+ def finally &block
88
+ self.callback &block
89
+ if @throttle
90
+ @throttle.times{ call }
91
+ else
92
+ @times.times{ call }
93
+ end
94
+ end
95
+
96
+ protected
97
+ def call
98
+ @worker += 1
99
+ @loop.call Proc.new{nextStep}, @opened, @worker
100
+ @opened += 1
101
+ if @debug
102
+ puts "worker: #{@worker} opened: #{@opened} finished: #{@finished}"
103
+ end
104
+ end
105
+
106
+ def nextStep
107
+ puts "ending" if @debug
108
+ @finished += 1
109
+ @worker -= 1
110
+ if @finished == @times
111
+ self.succeed
112
+ else
113
+ call if @opened < @times
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ # Repeat sequentially an action
120
+ class AdLib
121
+ include EM::Deferrable
122
+
123
+ def initialize times, &block
124
+ @cpt = 0
125
+ @times = times
126
+ @loop = block
127
+ self
128
+ end
129
+
130
+ def finally &block
131
+ self.callback(&block)
132
+ self.nextStep
133
+ end
134
+
135
+ def nextStep
136
+ if @cpt == @times
137
+ self.succeed
138
+ else
139
+ @loop.call( Proc.new {nextStep}, @cpt)
140
+ @cpt += 1
141
+ end
142
+ end
143
+ end
144
+
145
+ # Until sick. Act again and again, until criteria
146
+ class AdNauseum
147
+ include EM::Deferrable
148
+
149
+ def initialize &block
150
+ @loop = block
151
+ self
152
+ end
153
+
154
+ def until &block
155
+ @criteria = block
156
+ self
157
+ end
158
+
159
+ def finally &block
160
+ self.callback &block
161
+ @loop.call( Proc.new { nextStep })
162
+ self
163
+ end
164
+
165
+ def nextStep
166
+ if @criteria.call
167
+ self.succeed
168
+ else
169
+ @loop.call( Proc.new { nextStep })
170
+ end
171
+ end
172
+ end
173
+
174
+ end
175
+ end
176
+
177
+ def quorum(times, &block)
178
+ EventMachine::Scenario::Quorum.new times, &block
179
+ end
180
+
181
+ def adlib(times, &block)
182
+ EventMachine::Scenario::AdLib.new times, &block
183
+ end
184
+
185
+ def abinitio(&block)
186
+ EventMachine::Scenario::AbInitio.new &block
187
+ end
188
+
189
+ alias sequence abinitio
190
+
191
+ def adnauseum(&block)
192
+ EventMachine::Scenario::AdNauseum.new &block
193
+ end
194
+
195
+ def quantumsatis(times, throttle=nil, &block)
196
+ EventMachine::Scenario::QuantumSatis.new times, throttle, &block
197
+ end
@@ -0,0 +1,25 @@
1
+ require "eventmachine"
2
+
3
+ module EventMachine
4
+ module Scenario
5
+
6
+ # Just like with em-http-request
7
+ class Multi
8
+ include EM::Deferrable
9
+
10
+ def initialize
11
+ @actions = 0
12
+ end
13
+
14
+ def add deferable
15
+ @actions += 1
16
+ deferable.callback do
17
+ @actions -= 1
18
+ self.succeed if @actions == 0
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,58 @@
1
+ require "eventmachine"
2
+
3
+ module EventMachine
4
+ module Scenario
5
+
6
+ class Sequence
7
+ include EM::Deferrable
8
+
9
+ # block must return a deferrable
10
+ def initialize &block
11
+ @action = []
12
+ @bag = Bag.new
13
+ block.call(@bag).callback do
14
+ @action[0].call
15
+ end
16
+ self
17
+ end
18
+
19
+ def then &block
20
+ size = @action.size + 1
21
+ @bag.incr
22
+ @action << proc {
23
+ defer = block.call(@bag, *@bag[size+1])
24
+ if size < @action.length
25
+ defer.callback do
26
+ @action[size].call
27
+ end
28
+ end
29
+ }
30
+ self
31
+ end
32
+
33
+ end
34
+
35
+ private
36
+ class Bag
37
+
38
+ def initialize
39
+ @datas = []
40
+ @poz = 0
41
+ end
42
+
43
+ def incr
44
+ @poz +=1
45
+ end
46
+
47
+ def return *data
48
+ @datas[@poz] = data
49
+ end
50
+
51
+ def [] poz
52
+ @datas[poz]
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ require "eventmachine"
2
+
3
+ module EventMachine
4
+ module Scenario
5
+
6
+ class Timer
7
+
8
+ include EM::Deferrable
9
+
10
+ def initialize timer, &block
11
+ self.callback &block
12
+ @id = EM.add_timer(timer) do
13
+ self.succeed
14
+ end
15
+ end
16
+
17
+ def cancel
18
+ EM.cancel_timer @id
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
data/lib/scenario.rb CHANGED
@@ -1,195 +1,7 @@
1
1
  require "eventmachine"
2
2
 
3
- module EventMachine
4
- # @see http://en.wikipedia.org/wiki/List_of_Latin_phrases
5
- module Scenario
6
-
7
- class Scenario
8
-
9
- end
10
-
11
- # from the start
12
- class AbInitio
13
- include EM::Deferrable
14
-
15
- def initialize &block
16
- @actions = AbInitioActions.new
17
- block.call @actions
18
- self
19
- end
20
-
21
- def nextStep
22
- if @actions.actions.length > 0
23
- @actions.actions.pop.succeed(Proc.new { nextStep })
24
- else
25
- self.succeed
26
- end
27
- end
28
-
29
- def finally &block
30
- self.callback &block
31
- @actions.actions.reverse!
32
- self.nextStep
33
- end
34
- end
35
-
36
- class AbInitioActions
37
- attr_accessor :actions
38
- def initialize
39
- @actions = []
40
- end
41
-
42
- def then &block
43
- d = EM::DefaultDeferrable.new
44
- d.callback(&block)
45
- @actions << d
46
- self
47
- end
48
-
49
- end
50
-
51
- #Trigger when a quota of actions is done
52
- class Quorum < Scenario
53
- include EM::Deferrable
54
-
55
- def initialize times, &block
56
- @times = times
57
- @loop = block
58
- self
59
- end
60
-
61
- def finally &block
62
- self.callback(&block)
63
- @loop.call( Proc.new {nextStep} )
64
- end
65
-
66
- protected
67
- def nextStep
68
- @times -= 1
69
- self.succeed(self) if @times == 0
70
- end
71
- end
72
-
73
- # As much as enough.
74
- # You wont lots of parralel workers, but not too much.
75
- class QuantumSatis
76
- include EM::Deferrable
77
-
78
- def initialize times, throttle=nil, &block
79
- @opened = 0
80
- @finished = 0
81
- @worker = 0
82
- @times = times
83
- @throttle = throttle
84
- @loop = block
85
- @debug = false
86
- end
87
-
88
- def finally &block
89
- self.callback &block
90
- if @throttle
91
- @throttle.times{ call }
92
- else
93
- @times.times{ call }
94
- end
95
- end
96
-
97
- protected
98
- def call
99
- @worker += 1
100
- @loop.call Proc.new{nextStep}, @opened, @worker
101
- @opened += 1
102
- if @debug
103
- puts "worker: #{@worker} opened: #{@opened} finished: #{@finished}"
104
- end
105
- end
106
-
107
- def nextStep
108
- puts "ending" if @debug
109
- @finished += 1
110
- @worker -= 1
111
- if @finished == @times
112
- self.succeed
113
- else
114
- call if @opened < @times
115
- end
116
- end
117
-
118
- end
119
-
120
- # Repeat sequentially an action
121
- class AdLib
122
- include EM::Deferrable
123
-
124
- def initialize times, &block
125
- @cpt = 0
126
- @times = times
127
- @loop = block
128
- self
129
- end
130
-
131
- def finally &block
132
- self.callback(&block)
133
- self.nextStep
134
- end
135
-
136
- def nextStep
137
- if @cpt == @times
138
- self.succeed
139
- else
140
- @loop.call( Proc.new {nextStep}, @cpt)
141
- @cpt += 1
142
- end
143
- end
144
- end
145
-
146
- # Until sick. Act again and again, until criteria
147
- class AdNauseum
148
- include EM::Deferrable
149
-
150
- def initialize &block
151
- @loop = block
152
- self
153
- end
154
-
155
- def until &block
156
- @criteria = block
157
- self
158
- end
159
-
160
- def finally &block
161
- self.callback &block
162
- @loop.call( Proc.new { nextStep })
163
- self
164
- end
165
-
166
- def nextStep
167
- if @criteria.call
168
- self.succeed
169
- else
170
- @loop.call( Proc.new { nextStep })
171
- end
172
- end
173
- end
174
- end
175
- end
176
-
177
- def quorum(times, &block)
178
- EventMachine::Scenario::Quorum.new times, &block
179
- end
180
-
181
- def adlib(times, &block)
182
- EventMachine::Scenario::AdLib.new times, &block
183
- end
184
-
185
- def abinitio(&block)
186
- EventMachine::Scenario::AbInitio.new &block
187
- end
188
-
189
- def adnauseum(&block)
190
- EventMachine::Scenario::AdNauseum.new &block
191
- end
192
-
193
- def quantumsatis(times, throttle=nil, &block)
194
- EventMachine::Scenario::QuantumSatis.new times, throttle, &block
195
- end
3
+ require "scenario/iterator"
4
+ require "scenario/multi"
5
+ require "scenario/timer"
6
+ require "scenario/sequence"
7
+ require "scenario/latin"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-scenario
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-08 00:00:00.000000000 Z
12
+ date: 2011-09-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &2152103240 !ruby/object:Gem::Requirement
16
+ requirement: &2152036200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.0.0.beta3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152103240
24
+ version_requirements: *2152036200
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &2152099300 !ruby/object:Gem::Requirement
27
+ requirement: &2160363040 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2152099300
35
+ version_requirements: *2160363040
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &2152093220 !ruby/object:Gem::Requirement
38
+ requirement: &2160375720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2152093220
46
+ version_requirements: *2160375720
47
47
  description: Handling simpler story with event machine's callback
48
48
  email: mathieu@garambrogne.net
49
49
  executables: []
@@ -53,6 +53,12 @@ extra_rdoc_files:
53
53
  files:
54
54
  - README.md
55
55
  - Gemfile
56
+ - lib/scenario/core.rb
57
+ - lib/scenario/iterator.rb
58
+ - lib/scenario/latin.rb
59
+ - lib/scenario/multi.rb
60
+ - lib/scenario/sequence.rb
61
+ - lib/scenario/timer.rb
56
62
  - lib/scenario.rb
57
63
  homepage: http://github.com/athoune/em-scenario
58
64
  licenses: []