asynchronic 0.1.0 → 0.2.0

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.
Files changed (37) hide show
  1. data/lib/asynchronic.rb +0 -2
  2. data/lib/asynchronic/data_store/helper.rb +42 -0
  3. data/lib/asynchronic/data_store/in_memory.rb +18 -22
  4. data/lib/asynchronic/data_store/key.rb +19 -1
  5. data/lib/asynchronic/data_store/lazy_store.rb +17 -0
  6. data/lib/asynchronic/data_store/lazy_value.rb +34 -0
  7. data/lib/asynchronic/data_store/readonly_store.rb +17 -0
  8. data/lib/asynchronic/data_store/redis.rb +16 -27
  9. data/lib/asynchronic/data_store/scoped_store.rb +52 -0
  10. data/lib/asynchronic/environment.rb +7 -27
  11. data/lib/asynchronic/job.rb +15 -27
  12. data/lib/asynchronic/process.rb +105 -76
  13. data/lib/asynchronic/queue_engine/in_memory.rb +5 -1
  14. data/lib/asynchronic/queue_engine/ost.rb +5 -1
  15. data/lib/asynchronic/queue_engine/synchronic.rb +68 -0
  16. data/lib/asynchronic/transparent_proxy.rb +52 -0
  17. data/lib/asynchronic/version.rb +1 -1
  18. data/spec/data_store/data_store_examples.rb +48 -32
  19. data/spec/data_store/in_memory_spec.rb +5 -0
  20. data/spec/data_store/key_spec.rb +36 -12
  21. data/spec/data_store/lazy_value_examples.rb +38 -0
  22. data/spec/data_store/redis_spec.rb +17 -0
  23. data/spec/data_store/scoped_store_spec.rb +60 -0
  24. data/spec/expectations.rb +7 -7
  25. data/spec/facade_spec.rb +15 -13
  26. data/spec/jobs.rb +70 -49
  27. data/spec/minitest_helper.rb +11 -1
  28. data/spec/process/life_cycle_examples.rb +149 -135
  29. data/spec/queue_engine/synchronic_spec.rb +27 -0
  30. data/spec/transparent_proxy_spec.rb +36 -0
  31. data/spec/worker/worker_examples.rb +1 -1
  32. metadata +117 -79
  33. checksums.yaml +0 -7
  34. data/lib/asynchronic/data_store/lookup.rb +0 -27
  35. data/lib/asynchronic/hash.rb +0 -31
  36. data/lib/asynchronic/runtime.rb +0 -40
  37. data/spec/data_store/lookup_spec.rb +0 -92
@@ -1,14 +1,15 @@
1
1
  require 'coverage_helper'
2
+ require 'asynchronic'
2
3
  require 'minitest/autorun'
3
4
  require 'minitest/great_expectations'
4
5
  require 'turn'
5
- require 'asynchronic'
6
6
  require 'jobs'
7
7
  require 'expectations'
8
8
 
9
9
  Turn.config do |c|
10
10
  c.format = :pretty
11
11
  c.natural = true
12
+ c.ansi = true
12
13
  end
13
14
 
14
15
  class Module
@@ -26,4 +27,13 @@ class Minitest::Spec
26
27
  Asynchronic::DataStore::Redis.new.clear
27
28
  Asynchronic::QueueEngine::Ost.new.clear
28
29
  end
30
+ end
31
+
32
+ module Asynchronic::DataStore::Helper
33
+ def dump
34
+ puts 'DataStore:'
35
+ each do |k,v|
36
+ puts "#{k}: #{v}"
37
+ end
38
+ end
29
39
  end
@@ -4,276 +4,290 @@ module LifeCycleExamples
4
4
 
5
5
  let(:queue) { env.default_queue }
6
6
 
7
- def execute_work(queue)
8
- env.load_process(queue.pop).execute
7
+ def create(type, params={})
8
+ env.create_process type, params
9
9
  end
10
10
 
11
- def enqueue(process, data={})
12
- process.enqueue(data).must_equal process.job.lookup.id
11
+ def execute(queue)
12
+ env.load_process(queue.pop).execute
13
13
  end
14
14
 
15
15
  it 'Basic' do
16
- process = env.build_process BasicJob
16
+ process = create BasicJob, input: 1
17
17
 
18
18
  process.must_be_initialized
19
+ process.must_have_params input: 1
19
20
  queue.must_be_empty
20
21
 
21
- enqueue process, input: 1
22
+ process.enqueue
22
23
 
23
24
  process.must_be_queued
24
- process.must_have input: 1
25
25
  queue.must_enqueued process
26
26
 
27
- execute_work queue
27
+ execute queue
28
28
 
29
29
  process.must_be_completed
30
- process.must_have input: 1, output: 2
30
+ process.result.must_equal 2
31
31
  queue.must_be_empty
32
32
  end
33
33
 
34
34
  it 'Sequential' do
35
- process = env.build_process SequentialJob
35
+ process = create SequentialJob, input: 50
36
36
 
37
37
  process.must_be_initialized
38
+ process.must_have_params input: 50
38
39
  queue.must_be_empty
39
40
 
40
- enqueue process, input: 50
41
+ process.enqueue
41
42
 
42
43
  process.must_be_queued
43
- process.processes.must_be_empty
44
- process.must_have input: 50
45
44
  queue.must_enqueued process
46
45
 
47
- execute_work queue
46
+ execute queue
48
47
 
49
48
  process.must_be_waiting
50
- process.processes(SequentialJob::Step1).must_be_queued
51
- process.processes(SequentialJob::Step2).must_be_pending
52
- process.must_have input: 50
53
- queue.must_enqueued process.processes(SequentialJob::Step1)
49
+ process[SequentialJob::Step1].must_be_queued
50
+ process[SequentialJob::Step1].must_have_params input: 50
51
+ process[SequentialJob::Step2].must_be_pending
52
+ process[SequentialJob::Step2].must_have_params input: 50
53
+ queue.must_enqueued process[SequentialJob::Step1]
54
54
 
55
- execute_work queue
55
+ execute queue
56
56
 
57
57
  process.must_be_waiting
58
- process.processes(SequentialJob::Step1).must_be_completed
59
- process.processes(SequentialJob::Step2).must_be_queued
60
- process.must_have input: 50, partial: 500
61
- queue.must_enqueued process.processes(SequentialJob::Step2)
58
+ process[SequentialJob::Step1].must_be_completed
59
+ process[SequentialJob::Step1].result.must_equal 500
60
+ process[SequentialJob::Step2].must_be_queued
61
+ queue.must_enqueued process[SequentialJob::Step2]
62
62
 
63
- execute_work queue
63
+ execute queue
64
64
 
65
65
  process.must_be_completed
66
- process.processes(SequentialJob::Step1).must_be_completed
67
- process.processes(SequentialJob::Step2).must_be_completed
68
- process.must_have input: 50, partial: 500, output: 5
66
+ process.result.must_be_nil
67
+ process[SequentialJob::Step2].must_be_completed
68
+ process[SequentialJob::Step2].result.must_equal 5
69
69
  queue.must_be_empty
70
70
  end
71
71
 
72
72
  it 'Graph' do
73
- process = env.build_process GraphJob
73
+ process = create GraphJob, input: 100
74
74
 
75
75
  process.must_be_initialized
76
+ process.must_have_params input: 100
76
77
  queue.must_be_empty
77
78
 
78
- enqueue process, input: 100
79
+ process.enqueue
79
80
 
80
81
  process.must_be_queued
81
- process.processes.must_be_empty
82
- process.must_have input: 100
83
82
  queue.must_enqueued process
84
83
 
85
- execute_work queue
84
+ execute queue
86
85
 
87
86
  process.must_be_waiting
88
- process.processes(GraphJob::Sum).must_be_queued
89
- process.processes(GraphJob::TenPercent).must_be_pending
90
- process.processes(GraphJob::TwentyPercent).must_be_pending
91
- process.processes(GraphJob::Total).must_be_pending
92
- process.must_have input: 100
93
- queue.must_enqueued process.processes(GraphJob::Sum)
87
+ process[GraphJob::Sum].must_be_queued
88
+ process[GraphJob::Sum].must_have_params input: 100
89
+ process[GraphJob::TenPercent].must_be_pending
90
+ process[GraphJob::TenPercent].must_have_params input: nil
91
+ process[GraphJob::TwentyPercent].must_be_pending
92
+ process[GraphJob::TwentyPercent].must_have_params input: nil
93
+ process[GraphJob::Total].must_be_pending
94
+ process[GraphJob::Total].must_have_params '10%' => nil, '20%' => nil
95
+ queue.must_enqueued process[GraphJob::Sum]
94
96
 
95
- execute_work queue
97
+ execute queue
96
98
 
97
99
  process.must_be_waiting
98
- process.processes(GraphJob::Sum).must_be_completed
99
- process.processes(GraphJob::TenPercent).must_be_queued
100
- process.processes(GraphJob::TwentyPercent).must_be_queued
101
- process.processes(GraphJob::Total).must_be_pending
102
- process.must_have input: 100, sum: 200
103
- queue.must_enqueued [process.processes(GraphJob::TenPercent), process.processes(GraphJob::TwentyPercent)]
100
+ process[GraphJob::Sum].must_be_completed
101
+ process[GraphJob::Sum].result.must_equal 200
102
+ process[GraphJob::TenPercent].must_be_queued
103
+ process[GraphJob::TenPercent].must_have_params input: 200
104
+ process[GraphJob::TwentyPercent].must_be_queued
105
+ process[GraphJob::TwentyPercent].must_have_params input: 200
106
+ process[GraphJob::Total].must_be_pending
107
+ queue.must_enqueued [process[GraphJob::TenPercent], process[GraphJob::TwentyPercent]]
104
108
 
105
- 2.times { execute_work queue }
109
+ 2.times { execute queue }
106
110
 
107
111
  process.must_be_waiting
108
- process.processes(GraphJob::Sum).must_be_completed
109
- process.processes(GraphJob::TenPercent).must_be_completed
110
- process.processes(GraphJob::TwentyPercent).must_be_completed
111
- process.processes(GraphJob::Total).must_be_queued
112
- process.must_have input: 100, sum: 200, '10%' => 20, '20%' => 40
113
- queue.must_enqueued process.processes(GraphJob::Total)
112
+ process[GraphJob::TenPercent].must_be_completed
113
+ process[GraphJob::TenPercent].result.must_equal 20
114
+ process[GraphJob::TwentyPercent].must_be_completed
115
+ process[GraphJob::TwentyPercent].result.must_equal 40
116
+ process[GraphJob::Total].must_be_queued
117
+ queue.must_enqueued process[GraphJob::Total]
114
118
 
115
- execute_work queue
119
+ execute queue
116
120
 
117
121
  process.must_be_completed
118
- process.processes(GraphJob::Sum).must_be_completed
119
- process.processes(GraphJob::TenPercent).must_be_completed
120
- process.processes(GraphJob::TwentyPercent).must_be_completed
121
- process.processes(GraphJob::Total).must_be_completed
122
- process.must_have input: 100, sum: 200, '10%' => 20, '20%' => 40, output: {'10%' => 20, '20%' => 40}
122
+ process.result.must_equal '10%' => 20, '20%' => 40
123
+ process[GraphJob::Total].must_be_completed
124
+ process[GraphJob::Total].result.must_equal '10%' => 20, '20%' => 40
123
125
  queue.must_be_empty
124
126
  end
125
127
 
126
128
  it 'Parallel' do
127
- process = env.build_process ParallelJob
129
+ process = create ParallelJob, input: 10, times: 3
128
130
 
129
131
  process.must_be_initialized
132
+ process.must_have_params input: 10, times: 3
130
133
  queue.must_be_empty
131
134
 
132
- enqueue process, input: 10, times: 3
135
+ process.enqueue
133
136
 
134
137
  process.must_be_queued
135
138
  process.processes.must_be_empty
136
- process.must_have input: 10, times: 3
137
139
  queue.must_enqueued process
138
140
 
139
- execute_work queue
141
+ execute queue
140
142
 
141
143
  process.must_be_waiting
142
- process.processes.each { |p| p.must_be_queued }
143
- process.must_have input: 10, times: 3
144
+ process.processes.count.must_equal 3
145
+ process.processes.each_with_index do |p,i|
146
+ p.must_be_queued
147
+ p.must_have_params input: 10, index: i
148
+ end
144
149
  queue.must_enqueued process.processes
145
150
 
146
- 3.times { execute_work queue }
151
+ 3.times { execute queue }
147
152
 
148
153
  process.must_be_completed
149
- process.processes.each { |p| p.must_be_completed }
150
- hash = Hash[3.times.map { |i| ["key_#{i}", 10 * i] }]
151
- process.must_have hash.merge(input: 10, times: 3)
154
+ process.result.must_equal 3
155
+ process.processes.each_with_index do |p,i|
156
+ p.must_be_completed
157
+ p.result.must_equal 10 * i
158
+ end
152
159
  queue.must_be_empty
153
160
  end
154
161
 
155
162
  it 'Nested' do
156
- process = env.build_process NestedJob
163
+ process = create NestedJob, input: 4
157
164
 
158
165
  process.must_be_initialized
166
+ process.must_have_params input: 4
159
167
  queue.must_be_empty
160
168
 
161
- enqueue process, input: 4
169
+ process.enqueue
162
170
 
163
171
  process.must_be_queued
164
172
  process.processes.must_be_empty
165
- process.must_have input: 4
166
173
  queue.must_enqueued process
167
174
 
168
- execute_work queue
175
+ execute queue
169
176
 
170
177
  process.must_be_waiting
171
- process.processes(NestedJob::Level1).must_be_queued
172
- process.processes(NestedJob::Level1).processes.must_be_empty
173
- process.must_have input: 4
174
- queue.must_enqueued process.processes(NestedJob::Level1)
178
+ process[NestedJob::Level1].must_be_queued
179
+ process[NestedJob::Level1].must_have_params input: 4
180
+ process[NestedJob::Level1].processes.must_be_empty
181
+ queue.must_enqueued process[NestedJob::Level1]
175
182
 
176
- execute_work queue
183
+ execute queue
177
184
 
178
185
  process.must_be_waiting
179
- process.processes(NestedJob::Level1).must_be_waiting
180
- process.processes(NestedJob::Level1).processes(NestedJob::Level1::Level2).must_be_queued
181
- process.must_have input: 5
182
- queue.must_enqueued process.processes(NestedJob::Level1).processes(NestedJob::Level1::Level2)
186
+ process[NestedJob::Level1].must_be_waiting
187
+ process[NestedJob::Level1][NestedJob::Level1::Level2].must_be_queued
188
+ process[NestedJob::Level1][NestedJob::Level1::Level2].must_have_params input: 5
189
+ queue.must_enqueued process[NestedJob::Level1][NestedJob::Level1::Level2]
183
190
 
184
- execute_work queue
191
+ execute queue
185
192
 
186
193
  process.must_be_completed
187
- process.processes(NestedJob::Level1).must_be_completed
188
- process.processes(NestedJob::Level1).processes(NestedJob::Level1::Level2).must_be_completed
189
- process.must_have input: 5, output: 25
194
+ process.result.must_equal 25
195
+ process[NestedJob::Level1].must_be_completed
196
+ process[NestedJob::Level1].result.must_equal 25
197
+ process[NestedJob::Level1][NestedJob::Level1::Level2].must_be_completed
198
+ process[NestedJob::Level1][NestedJob::Level1::Level2].result.must_equal 25
190
199
  queue.must_be_empty
191
200
  end
192
201
 
193
- it 'Dependency alias' do
194
- process = env.build_process DependencyAliasJob
202
+ it 'Alias' do
203
+ process = create AliasJob
195
204
 
196
205
  process.must_be_initialized
197
206
  queue.must_be_empty
198
207
 
199
- enqueue process
208
+ process.enqueue
200
209
 
201
210
  process.must_be_queued
202
211
  process.processes.must_be_empty
203
- process.data.must_be_empty
204
212
  queue.must_enqueued process
205
213
 
206
- execute_work queue
214
+ execute queue
207
215
 
208
216
  process.must_be_waiting
209
- process.processes(:word_1).must_be_queued
210
- process.processes(:word_2).must_be_pending
211
- process.processes(:word_3).must_be_pending
212
- process.data.must_be_empty
213
- queue.must_enqueued process.processes(:word_1)
217
+ process[:word_1].must_be_queued
218
+ process[:word_1].must_have_params text: 'Take'
219
+ process[:word_2].must_be_pending
220
+ process[:word_2].must_have_params text: 'it', prefix: nil
221
+ process[:word_3].must_be_pending
222
+ process[:word_3].must_have_params text: 'easy', prefix: nil
223
+ queue.must_enqueued process[:word_1]
214
224
 
215
- execute_work queue
225
+ execute queue
216
226
 
217
227
  process.must_be_waiting
218
- process.processes(:word_1).must_be_completed
219
- process.processes(:word_2).must_be_queued
220
- process.processes(:word_3).must_be_pending
221
- process.must_have text: 'Take'
222
- queue.must_enqueued process.processes(:word_2)
228
+ process[:word_1].must_be_completed
229
+ process[:word_1].result.must_equal 'Take'
230
+ process[:word_2].must_be_queued
231
+ process[:word_2].must_have_params text: 'it', prefix: 'Take'
232
+ process[:word_3].must_be_pending
233
+ queue.must_enqueued process[:word_2]
223
234
 
224
- execute_work queue
235
+ execute queue
225
236
 
226
237
  process.must_be_waiting
227
- process.processes(:word_1).must_be_completed
228
- process.processes(:word_2).must_be_completed
229
- process.processes(:word_3).must_be_queued
230
- process.must_have text: 'Take it'
231
- queue.must_enqueued process.processes(:word_3)
238
+ process[:word_1].must_be_completed
239
+ process[:word_2].must_be_completed
240
+ process[:word_2].result.must_equal 'Take it'
241
+ process[:word_3].must_be_queued
242
+ process[:word_3].must_have_params text: 'easy', prefix: 'Take it'
243
+ queue.must_enqueued process[:word_3]
232
244
 
233
- execute_work queue
245
+ execute queue
234
246
 
235
247
  process.must_be_completed
236
- process.processes(:word_1).must_be_completed
237
- process.processes(:word_2).must_be_completed
238
- process.processes(:word_3).must_be_completed
239
- process.must_have text: 'Take it easy'
248
+ process.result.must_equal 'Take it easy'
249
+ process[:word_1].must_be_completed
250
+ process[:word_2].must_be_completed
251
+ process[:word_3].must_be_completed
252
+ process[:word_3].result.must_equal 'Take it easy'
240
253
  queue.must_be_empty
241
254
  end
242
255
 
243
256
  it 'Custom queue' do
244
- process = env.build_process CustomQueueJob
257
+ process = create CustomQueueJob, input: 'hello'
245
258
 
246
259
  process.must_be_initialized
247
-
260
+ process.must_have_params input: 'hello'
261
+
248
262
  env.queue(:queue_1).must_be_empty
249
263
  env.queue(:queue_2).must_be_empty
250
264
  env.queue(:queue_3).must_be_empty
251
265
 
252
- enqueue process, input: 'hello'
266
+ process.enqueue
253
267
 
254
268
  process.must_be_queued
255
269
  process.processes.must_be_empty
256
- process.must_have input: 'hello'
257
270
 
258
271
  env.queue(:queue_1).must_enqueued process
259
272
  env.queue(:queue_2).must_be_empty
260
273
  env.queue(:queue_3).must_be_empty
261
274
 
262
- execute_work env.queue(:queue_1)
275
+ execute env.queue(:queue_1)
263
276
 
264
277
  process.must_be_waiting
265
- process.processes(CustomQueueJob::Reverse).must_be_queued
266
- process.must_have input: 'hello'
278
+ process[CustomQueueJob::Reverse].must_be_queued
279
+ process[CustomQueueJob::Reverse].must_have_params input: 'hello'
267
280
 
268
281
  env.queue(:queue_1).must_be_empty
269
- env.queue(:queue_2).must_enqueued process.processes(CustomQueueJob::Reverse)
282
+ env.queue(:queue_2).must_enqueued process[CustomQueueJob::Reverse]
270
283
  env.queue(:queue_3).must_be_empty
271
284
 
272
- execute_work env.queue(:queue_2)
285
+ execute env.queue(:queue_2)
273
286
 
274
287
  process.must_be_completed
275
- process.processes(CustomQueueJob::Reverse).must_be_completed
276
- process.must_have input: 'hello', output: 'olleh'
288
+ process.result.must_equal 'olleh'
289
+ process[CustomQueueJob::Reverse].must_be_completed
290
+ process[CustomQueueJob::Reverse].result.must_equal 'olleh'
277
291
 
278
292
  env.queue(:queue_1).must_be_empty
279
293
  env.queue(:queue_2).must_be_empty
@@ -281,17 +295,17 @@ module LifeCycleExamples
281
295
  end
282
296
 
283
297
  it 'Exception' do
284
- process = env.build_process ExceptionJob
298
+ process = create ExceptionJob
285
299
 
286
300
  process.must_be_initialized
287
301
  queue.must_be_empty
288
302
 
289
- enqueue process
303
+ process.enqueue
290
304
 
291
305
  process.must_be_queued
292
306
  queue.must_enqueued process
293
307
 
294
- execute_work queue
308
+ execute queue
295
309
 
296
310
  process.must_be_aborted
297
311
  process.error.must_be_instance_of Asynchronic::Error
@@ -299,31 +313,31 @@ module LifeCycleExamples
299
313
  end
300
314
 
301
315
  it 'Inner exception' do
302
- process = env.build_process InnerExceptionJob
316
+ process = create InnerExceptionJob
303
317
 
304
318
  process.must_be_initialized
305
319
  queue.must_be_empty
306
320
 
307
- enqueue process
321
+ process.enqueue
308
322
 
309
323
  process.must_be_queued
310
324
  queue.must_enqueued process
311
325
 
312
- execute_work queue
326
+ execute queue
313
327
 
314
328
  process.must_be_waiting
315
- process.processes(ExceptionJob).must_be_queued
316
- queue.must_enqueued process.processes(ExceptionJob)
329
+ process[ExceptionJob].must_be_queued
330
+ queue.must_enqueued process[ExceptionJob]
317
331
 
318
- execute_work queue
332
+ execute queue
319
333
 
320
334
  process.must_be_aborted
321
335
  process.error.must_be_instance_of Asynchronic::Error
322
336
  process.error.message.must_equal 'Error caused by ExceptionJob'
323
337
 
324
- process.processes(ExceptionJob).must_be_aborted
325
- process.processes(ExceptionJob).error.must_be_instance_of Asynchronic::Error
326
- process.processes(ExceptionJob).error.message.must_equal 'Error for test'
338
+ process[ExceptionJob].must_be_aborted
339
+ process[ExceptionJob].error.must_be_instance_of Asynchronic::Error
340
+ process[ExceptionJob].error.message.must_equal 'Error for test'
327
341
  end
328
342
 
329
343
  end