em-scenario 0.0.3 → 0.0.4

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/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: []