asynchronic 0.0.1 → 0.1.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/README.md +0 -70
- data/Rakefile +7 -0
- data/asynchronic.gemspec +5 -1
- data/lib/asynchronic/data_store/in_memory.rb +47 -0
- data/lib/asynchronic/data_store/key.rb +15 -0
- data/lib/asynchronic/data_store/lookup.rb +27 -0
- data/lib/asynchronic/data_store/redis.rb +52 -0
- data/lib/asynchronic/environment.rb +57 -0
- data/lib/asynchronic/error.rb +13 -0
- data/lib/asynchronic/hash.rb +31 -0
- data/lib/asynchronic/job.rb +46 -0
- data/lib/asynchronic/process.rb +117 -48
- data/lib/asynchronic/queue_engine/in_memory.rb +72 -0
- data/lib/asynchronic/queue_engine/ost.rb +73 -0
- data/lib/asynchronic/runtime.rb +40 -0
- data/lib/asynchronic/version.rb +1 -1
- data/lib/asynchronic/worker.rb +27 -18
- data/lib/asynchronic.rb +17 -32
- data/spec/coverage_helper.rb +0 -6
- data/spec/data_store/data_store_examples.rb +62 -0
- data/spec/data_store/in_memory_spec.rb +10 -0
- data/spec/data_store/key_spec.rb +36 -0
- data/spec/data_store/lookup_spec.rb +92 -0
- data/spec/data_store/redis_spec.rb +14 -0
- data/spec/expectations.rb +89 -0
- data/spec/facade_spec.rb +61 -0
- data/spec/jobs.rb +123 -33
- data/spec/minitest_helper.rb +12 -14
- data/spec/process/life_cycle_examples.rb +329 -0
- data/spec/process/life_cycle_in_memory_spec.rb +11 -0
- data/spec/process/life_cycle_redis_spec.rb +15 -0
- data/spec/queue_engine/in_memory_spec.rb +11 -0
- data/spec/queue_engine/ost_spec.rb +15 -0
- data/spec/queue_engine/queue_engine_examples.rb +47 -0
- data/spec/worker/in_memory_spec.rb +11 -0
- data/spec/worker/redis_spec.rb +16 -0
- data/spec/worker/worker_examples.rb +49 -0
- metadata +111 -18
- data/lib/asynchronic/persistent.rb +0 -61
- data/lib/asynchronic/pipeline.rb +0 -23
- data/spec/integration_spec.rb +0 -122
- data/spec/persistent_spec.rb +0 -88
data/spec/jobs.rb
CHANGED
@@ -1,58 +1,148 @@
|
|
1
|
-
class
|
2
|
-
|
1
|
+
class BasicJob < Asynchronic::Job
|
2
|
+
define do
|
3
|
+
data[:output] = data[:input] + 1
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
class SequentialJob < Asynchronic::Job
|
9
|
+
|
10
|
+
define do
|
11
|
+
define_job Step1
|
12
|
+
define_job Step2, dependency: Step1
|
13
|
+
end
|
14
|
+
|
15
|
+
class Step1 < Asynchronic::Job
|
16
|
+
define do
|
17
|
+
data[:partial] = data[:input] * 10
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Step2 < Asynchronic::Job
|
22
|
+
define do
|
23
|
+
data[:output] = data[:partial] / 100
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
class GraphJob < Asynchronic::Job
|
31
|
+
|
32
|
+
define do
|
33
|
+
define_job Sum
|
34
|
+
define_job TenPercent, dependency: Sum
|
35
|
+
define_job TwentyPercent, dependency: Sum
|
36
|
+
define_job Total, dependencies: [TenPercent, TwentyPercent]
|
37
|
+
end
|
38
|
+
|
39
|
+
class Sum < Asynchronic::Job
|
40
|
+
define do
|
41
|
+
data[:sum] = data[:input] + 100
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class TenPercent < Asynchronic::Job
|
46
|
+
define do
|
47
|
+
data['10%'] = data[:sum] * 0.1
|
48
|
+
end
|
49
|
+
end
|
3
50
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
51
|
+
class TwentyPercent < Asynchronic::Job
|
52
|
+
define do
|
53
|
+
data['20%'] = data[:sum] * 0.2
|
54
|
+
end
|
8
55
|
end
|
9
56
|
|
10
|
-
|
11
|
-
|
57
|
+
class Total < Asynchronic::Job
|
58
|
+
define do
|
59
|
+
data[:output] = {'10%' => data['10%'], '20%' => data['20%']}
|
60
|
+
end
|
12
61
|
end
|
13
62
|
|
14
|
-
|
15
|
-
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
class ParallelJob < Asynchronic::Job
|
67
|
+
define do
|
68
|
+
data[:times].times do |i|
|
69
|
+
define_job Child, local: {index: i}
|
70
|
+
end
|
16
71
|
end
|
17
72
|
|
18
|
-
|
19
|
-
|
73
|
+
class Child < Asynchronic::Job
|
74
|
+
define do
|
75
|
+
data["key_#{index}"] = data[:input] * index
|
76
|
+
end
|
20
77
|
end
|
78
|
+
end
|
21
79
|
|
22
|
-
private
|
23
80
|
|
24
|
-
|
25
|
-
|
81
|
+
class NestedJob < Asynchronic::Job
|
82
|
+
define do
|
83
|
+
define_job Level1
|
84
|
+
end
|
85
|
+
|
86
|
+
class Level1 < Asynchronic::Job
|
87
|
+
define do
|
88
|
+
data[:input] += 1
|
89
|
+
define_job Level2
|
90
|
+
end
|
91
|
+
|
92
|
+
class Level2 < Asynchronic::Job
|
93
|
+
define do
|
94
|
+
data[:output] = data[:input] ** 2
|
95
|
+
end
|
96
|
+
end
|
26
97
|
end
|
27
98
|
end
|
28
99
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
100
|
+
|
101
|
+
class DependencyAliasJob < Asynchronic::Job
|
102
|
+
define do
|
103
|
+
define_job Write, local: {text: 'Take'}, alias: :word_1
|
104
|
+
define_job Write, local: {text: 'it'}, alias: :word_2, dependency: :word_1
|
105
|
+
define_job Write, local: {text: 'easy'}, alias: :word_3, dependency: :word_2
|
106
|
+
end
|
107
|
+
|
108
|
+
class Write < Asynchronic::Job
|
109
|
+
define do
|
110
|
+
data[:text] = "#{data[:text]} #{text}".strip
|
111
|
+
end
|
33
112
|
end
|
34
113
|
end
|
35
114
|
|
36
|
-
|
37
|
-
|
38
|
-
queue :
|
39
|
-
|
40
|
-
|
41
|
-
Registry.add ctx[:value1] + 1
|
115
|
+
|
116
|
+
class CustomQueueJob < Asynchronic::Job
|
117
|
+
queue :queue_1
|
118
|
+
define do
|
119
|
+
define_job Reverse, queue: :queue_2
|
42
120
|
end
|
43
|
-
|
44
|
-
|
121
|
+
|
122
|
+
class Reverse < Asynchronic::Job
|
123
|
+
queue :queue_3
|
124
|
+
define do
|
125
|
+
data[:output] = data[:input].reverse
|
126
|
+
end
|
45
127
|
end
|
46
128
|
end
|
47
129
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
130
|
+
|
131
|
+
class ExceptionJob < Asynchronic::Job
|
132
|
+
define do
|
133
|
+
raise 'Error for test'
|
52
134
|
end
|
53
|
-
|
54
|
-
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
class InnerExceptionJob < Asynchronic::Job
|
139
|
+
define do
|
140
|
+
define_job ExceptionJob
|
55
141
|
end
|
56
142
|
end
|
57
143
|
|
58
144
|
|
145
|
+
class WorkerJob < Asynchronic::Job
|
146
|
+
define do
|
147
|
+
end
|
148
|
+
end
|
data/spec/minitest_helper.rb
CHANGED
@@ -1,31 +1,29 @@
|
|
1
1
|
require 'coverage_helper'
|
2
2
|
require 'minitest/autorun'
|
3
|
+
require 'minitest/great_expectations'
|
3
4
|
require 'turn'
|
4
5
|
require 'asynchronic'
|
6
|
+
require 'jobs'
|
7
|
+
require 'expectations'
|
5
8
|
|
6
9
|
Turn.config do |c|
|
7
10
|
c.format = :pretty
|
8
11
|
c.natural = true
|
9
12
|
end
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Asynchronic.connect_redis host: 'localhost', port: 6379
|
16
|
-
|
17
|
-
Asynchronic.default_queue = 'asynchronic_test'
|
14
|
+
class Module
|
15
|
+
include Minitest::Spec::DSL
|
16
|
+
end
|
18
17
|
|
19
|
-
Asynchronic.
|
18
|
+
Asynchronic.logger.level = Logger::FATAL
|
20
19
|
|
21
|
-
class
|
22
|
-
|
20
|
+
class Minitest::Spec
|
23
21
|
before do
|
24
|
-
|
22
|
+
Asynchronic.restore_default_configuration
|
25
23
|
end
|
26
24
|
|
27
|
-
|
28
|
-
Redis.
|
25
|
+
after do
|
26
|
+
Asynchronic::DataStore::Redis.new.clear
|
27
|
+
Asynchronic::QueueEngine::Ost.new.clear
|
29
28
|
end
|
30
|
-
|
31
29
|
end
|
@@ -0,0 +1,329 @@
|
|
1
|
+
module LifeCycleExamples
|
2
|
+
|
3
|
+
let(:env) { Asynchronic::Environment.new queue_engine, data_store }
|
4
|
+
|
5
|
+
let(:queue) { env.default_queue }
|
6
|
+
|
7
|
+
def execute_work(queue)
|
8
|
+
env.load_process(queue.pop).execute
|
9
|
+
end
|
10
|
+
|
11
|
+
def enqueue(process, data={})
|
12
|
+
process.enqueue(data).must_equal process.job.lookup.id
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'Basic' do
|
16
|
+
process = env.build_process BasicJob
|
17
|
+
|
18
|
+
process.must_be_initialized
|
19
|
+
queue.must_be_empty
|
20
|
+
|
21
|
+
enqueue process, input: 1
|
22
|
+
|
23
|
+
process.must_be_queued
|
24
|
+
process.must_have input: 1
|
25
|
+
queue.must_enqueued process
|
26
|
+
|
27
|
+
execute_work queue
|
28
|
+
|
29
|
+
process.must_be_completed
|
30
|
+
process.must_have input: 1, output: 2
|
31
|
+
queue.must_be_empty
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'Sequential' do
|
35
|
+
process = env.build_process SequentialJob
|
36
|
+
|
37
|
+
process.must_be_initialized
|
38
|
+
queue.must_be_empty
|
39
|
+
|
40
|
+
enqueue process, input: 50
|
41
|
+
|
42
|
+
process.must_be_queued
|
43
|
+
process.processes.must_be_empty
|
44
|
+
process.must_have input: 50
|
45
|
+
queue.must_enqueued process
|
46
|
+
|
47
|
+
execute_work queue
|
48
|
+
|
49
|
+
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)
|
54
|
+
|
55
|
+
execute_work queue
|
56
|
+
|
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)
|
62
|
+
|
63
|
+
execute_work queue
|
64
|
+
|
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
|
69
|
+
queue.must_be_empty
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'Graph' do
|
73
|
+
process = env.build_process GraphJob
|
74
|
+
|
75
|
+
process.must_be_initialized
|
76
|
+
queue.must_be_empty
|
77
|
+
|
78
|
+
enqueue process, input: 100
|
79
|
+
|
80
|
+
process.must_be_queued
|
81
|
+
process.processes.must_be_empty
|
82
|
+
process.must_have input: 100
|
83
|
+
queue.must_enqueued process
|
84
|
+
|
85
|
+
execute_work queue
|
86
|
+
|
87
|
+
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)
|
94
|
+
|
95
|
+
execute_work queue
|
96
|
+
|
97
|
+
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)]
|
104
|
+
|
105
|
+
2.times { execute_work queue }
|
106
|
+
|
107
|
+
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)
|
114
|
+
|
115
|
+
execute_work queue
|
116
|
+
|
117
|
+
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}
|
123
|
+
queue.must_be_empty
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'Parallel' do
|
127
|
+
process = env.build_process ParallelJob
|
128
|
+
|
129
|
+
process.must_be_initialized
|
130
|
+
queue.must_be_empty
|
131
|
+
|
132
|
+
enqueue process, input: 10, times: 3
|
133
|
+
|
134
|
+
process.must_be_queued
|
135
|
+
process.processes.must_be_empty
|
136
|
+
process.must_have input: 10, times: 3
|
137
|
+
queue.must_enqueued process
|
138
|
+
|
139
|
+
execute_work queue
|
140
|
+
|
141
|
+
process.must_be_waiting
|
142
|
+
process.processes.each { |p| p.must_be_queued }
|
143
|
+
process.must_have input: 10, times: 3
|
144
|
+
queue.must_enqueued process.processes
|
145
|
+
|
146
|
+
3.times { execute_work queue }
|
147
|
+
|
148
|
+
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)
|
152
|
+
queue.must_be_empty
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'Nested' do
|
156
|
+
process = env.build_process NestedJob
|
157
|
+
|
158
|
+
process.must_be_initialized
|
159
|
+
queue.must_be_empty
|
160
|
+
|
161
|
+
enqueue process, input: 4
|
162
|
+
|
163
|
+
process.must_be_queued
|
164
|
+
process.processes.must_be_empty
|
165
|
+
process.must_have input: 4
|
166
|
+
queue.must_enqueued process
|
167
|
+
|
168
|
+
execute_work queue
|
169
|
+
|
170
|
+
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)
|
175
|
+
|
176
|
+
execute_work queue
|
177
|
+
|
178
|
+
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)
|
183
|
+
|
184
|
+
execute_work queue
|
185
|
+
|
186
|
+
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
|
190
|
+
queue.must_be_empty
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'Dependency alias' do
|
194
|
+
process = env.build_process DependencyAliasJob
|
195
|
+
|
196
|
+
process.must_be_initialized
|
197
|
+
queue.must_be_empty
|
198
|
+
|
199
|
+
enqueue process
|
200
|
+
|
201
|
+
process.must_be_queued
|
202
|
+
process.processes.must_be_empty
|
203
|
+
process.data.must_be_empty
|
204
|
+
queue.must_enqueued process
|
205
|
+
|
206
|
+
execute_work queue
|
207
|
+
|
208
|
+
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)
|
214
|
+
|
215
|
+
execute_work queue
|
216
|
+
|
217
|
+
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)
|
223
|
+
|
224
|
+
execute_work queue
|
225
|
+
|
226
|
+
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)
|
232
|
+
|
233
|
+
execute_work queue
|
234
|
+
|
235
|
+
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'
|
240
|
+
queue.must_be_empty
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'Custom queue' do
|
244
|
+
process = env.build_process CustomQueueJob
|
245
|
+
|
246
|
+
process.must_be_initialized
|
247
|
+
|
248
|
+
env.queue(:queue_1).must_be_empty
|
249
|
+
env.queue(:queue_2).must_be_empty
|
250
|
+
env.queue(:queue_3).must_be_empty
|
251
|
+
|
252
|
+
enqueue process, input: 'hello'
|
253
|
+
|
254
|
+
process.must_be_queued
|
255
|
+
process.processes.must_be_empty
|
256
|
+
process.must_have input: 'hello'
|
257
|
+
|
258
|
+
env.queue(:queue_1).must_enqueued process
|
259
|
+
env.queue(:queue_2).must_be_empty
|
260
|
+
env.queue(:queue_3).must_be_empty
|
261
|
+
|
262
|
+
execute_work env.queue(:queue_1)
|
263
|
+
|
264
|
+
process.must_be_waiting
|
265
|
+
process.processes(CustomQueueJob::Reverse).must_be_queued
|
266
|
+
process.must_have input: 'hello'
|
267
|
+
|
268
|
+
env.queue(:queue_1).must_be_empty
|
269
|
+
env.queue(:queue_2).must_enqueued process.processes(CustomQueueJob::Reverse)
|
270
|
+
env.queue(:queue_3).must_be_empty
|
271
|
+
|
272
|
+
execute_work env.queue(:queue_2)
|
273
|
+
|
274
|
+
process.must_be_completed
|
275
|
+
process.processes(CustomQueueJob::Reverse).must_be_completed
|
276
|
+
process.must_have input: 'hello', output: 'olleh'
|
277
|
+
|
278
|
+
env.queue(:queue_1).must_be_empty
|
279
|
+
env.queue(:queue_2).must_be_empty
|
280
|
+
env.queue(:queue_3).must_be_empty
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'Exception' do
|
284
|
+
process = env.build_process ExceptionJob
|
285
|
+
|
286
|
+
process.must_be_initialized
|
287
|
+
queue.must_be_empty
|
288
|
+
|
289
|
+
enqueue process
|
290
|
+
|
291
|
+
process.must_be_queued
|
292
|
+
queue.must_enqueued process
|
293
|
+
|
294
|
+
execute_work queue
|
295
|
+
|
296
|
+
process.must_be_aborted
|
297
|
+
process.error.must_be_instance_of Asynchronic::Error
|
298
|
+
process.error.message.must_equal 'Error for test'
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'Inner exception' do
|
302
|
+
process = env.build_process InnerExceptionJob
|
303
|
+
|
304
|
+
process.must_be_initialized
|
305
|
+
queue.must_be_empty
|
306
|
+
|
307
|
+
enqueue process
|
308
|
+
|
309
|
+
process.must_be_queued
|
310
|
+
queue.must_enqueued process
|
311
|
+
|
312
|
+
execute_work queue
|
313
|
+
|
314
|
+
process.must_be_waiting
|
315
|
+
process.processes(ExceptionJob).must_be_queued
|
316
|
+
queue.must_enqueued process.processes(ExceptionJob)
|
317
|
+
|
318
|
+
execute_work queue
|
319
|
+
|
320
|
+
process.must_be_aborted
|
321
|
+
process.error.must_be_instance_of Asynchronic::Error
|
322
|
+
process.error.message.must_equal 'Error caused by ExceptionJob'
|
323
|
+
|
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'
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './life_cycle_examples.rb'
|
3
|
+
|
4
|
+
describe Asynchronic::Process, 'Life cycle - InMemory' do
|
5
|
+
|
6
|
+
let(:queue_engine) { Asynchronic::QueueEngine::InMemory.new }
|
7
|
+
let(:data_store) { Asynchronic::DataStore::InMemory.new }
|
8
|
+
|
9
|
+
include LifeCycleExamples
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './life_cycle_examples.rb'
|
3
|
+
|
4
|
+
describe Asynchronic::Process, 'Life cycle - Redis' do
|
5
|
+
|
6
|
+
let(:queue_engine) { Asynchronic::QueueEngine::Ost.new }
|
7
|
+
let(:data_store) { Asynchronic::DataStore::Redis.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Redis.current.flushdb
|
11
|
+
end
|
12
|
+
|
13
|
+
include LifeCycleExamples
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './queue_engine_examples'
|
3
|
+
|
4
|
+
describe Asynchronic::QueueEngine::InMemory do
|
5
|
+
|
6
|
+
let(:engine) { Asynchronic::QueueEngine::InMemory.new }
|
7
|
+
let(:listener) { Asynchronic::QueueEngine::InMemory::Listener.new }
|
8
|
+
|
9
|
+
include QueueEngineExamples
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './queue_engine_examples'
|
3
|
+
|
4
|
+
describe Asynchronic::QueueEngine::Ost do
|
5
|
+
|
6
|
+
let(:engine) { Asynchronic::QueueEngine::Ost.new }
|
7
|
+
let(:listener) { Asynchronic::QueueEngine::Ost::Listener.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
engine.clear
|
11
|
+
end
|
12
|
+
|
13
|
+
include QueueEngineExamples
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module QueueEngineExamples
|
2
|
+
|
3
|
+
let(:queue) { engine[:test_queue] }
|
4
|
+
|
5
|
+
it 'Engine' do
|
6
|
+
engine.queues.must_be_empty
|
7
|
+
|
8
|
+
queue = engine[:test_engine]
|
9
|
+
queue.must_be_instance_of engine.class.const_get(:Queue)
|
10
|
+
engine.queues.must_equal [:test_engine]
|
11
|
+
|
12
|
+
engine[:test_engine].must_equal queue
|
13
|
+
|
14
|
+
engine.clear
|
15
|
+
engine.queues.must_be_empty
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'Queue (push/pop)' do
|
19
|
+
queue.must_be_empty
|
20
|
+
|
21
|
+
queue.push 'msg_1'
|
22
|
+
queue.push 'msg_2'
|
23
|
+
|
24
|
+
queue.size.must_equal 2
|
25
|
+
queue.to_a.must_equal %w(msg_1 msg_2)
|
26
|
+
|
27
|
+
queue.pop.must_equal 'msg_1'
|
28
|
+
|
29
|
+
queue.size.must_equal 1
|
30
|
+
queue.to_a.must_equal %w(msg_2)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'Listener' do
|
34
|
+
queue.push 'msg_1'
|
35
|
+
queue.push 'msg_2'
|
36
|
+
|
37
|
+
messages = []
|
38
|
+
|
39
|
+
listener.listen(queue) do |msg|
|
40
|
+
messages << msg
|
41
|
+
listener.stop if queue.empty?
|
42
|
+
end
|
43
|
+
|
44
|
+
messages.must_equal %w(msg_1 msg_2)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './worker_examples'
|
3
|
+
|
4
|
+
describe Asynchronic::Worker, 'InMemory' do
|
5
|
+
|
6
|
+
let(:queue_engine) { Asynchronic::QueueEngine::InMemory.new }
|
7
|
+
let(:data_store) { Asynchronic::DataStore::InMemory.new }
|
8
|
+
|
9
|
+
include WorkerExamples
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
require_relative './worker_examples'
|
3
|
+
|
4
|
+
describe Asynchronic::Worker, 'Redis' do
|
5
|
+
|
6
|
+
let(:queue_engine) { Asynchronic::QueueEngine::Ost.new }
|
7
|
+
let(:data_store) { Asynchronic::DataStore::Redis.new }
|
8
|
+
|
9
|
+
before do
|
10
|
+
data_store.clear
|
11
|
+
queue_engine.clear
|
12
|
+
end
|
13
|
+
|
14
|
+
include WorkerExamples
|
15
|
+
|
16
|
+
end
|