asynchronic 3.0.1 → 4.0.1
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 +5 -5
- data/.travis.yml +7 -10
- data/README.md +1 -2
- data/asynchronic.gemspec +2 -3
- data/lib/asynchronic.rb +8 -0
- data/lib/asynchronic/data_store/in_memory.rb +17 -15
- data/lib/asynchronic/data_store/key.rb +3 -3
- data/lib/asynchronic/data_store/lazy_value.rb +5 -3
- data/lib/asynchronic/data_store/redis.rb +22 -14
- data/lib/asynchronic/data_store/scoped_store.rb +18 -19
- data/lib/asynchronic/environment.rb +3 -3
- data/lib/asynchronic/error.rb +2 -3
- data/lib/asynchronic/garbage_collector.rb +2 -1
- data/lib/asynchronic/job.rb +12 -12
- data/lib/asynchronic/notifier/broadcaster.rb +8 -4
- data/lib/asynchronic/process.rb +42 -40
- data/lib/asynchronic/queue_engine/in_memory.rb +17 -11
- data/lib/asynchronic/queue_engine/ost.rb +7 -5
- data/lib/asynchronic/queue_engine/synchronic.rb +19 -7
- data/lib/asynchronic/version.rb +1 -1
- data/lib/asynchronic/worker.rb +7 -10
- data/spec/data_store/data_store_examples.rb +17 -9
- data/spec/data_store/in_memory_spec.rb +0 -2
- data/spec/data_store/key_spec.rb +1 -1
- data/spec/data_store/lazy_value_examples.rb +7 -5
- data/spec/data_store/redis_spec.rb +4 -10
- data/spec/expectations.rb +2 -2
- data/spec/facade_spec.rb +3 -3
- data/spec/jobs.rb +10 -10
- data/spec/minitest_helper.rb +5 -12
- data/spec/process/life_cycle_examples.rb +25 -23
- data/spec/process/life_cycle_in_memory_spec.rb +0 -1
- data/spec/process/life_cycle_redis_spec.rb +0 -1
- data/spec/queue_engine/in_memory_spec.rb +1 -3
- data/spec/queue_engine/ost_spec.rb +1 -7
- data/spec/queue_engine/queue_engine_examples.rb +17 -9
- data/spec/queue_engine/synchronic_spec.rb +1 -1
- data/spec/worker/in_memory_spec.rb +1 -2
- data/spec/worker/redis_spec.rb +0 -6
- data/spec/worker/worker_examples.rb +6 -4
- metadata +11 -20
data/spec/data_store/key_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module LazyValueExamples
|
2
2
|
|
3
|
+
extend Minitest::Spec::DSL
|
4
|
+
|
3
5
|
def lazy_value(key)
|
4
6
|
Asynchronic::DataStore::LazyValue.new data_store, key
|
5
7
|
end
|
@@ -7,25 +9,25 @@ module LazyValueExamples
|
|
7
9
|
it 'Get' do
|
8
10
|
value = lazy_value :key
|
9
11
|
value.must_be_nil
|
10
|
-
|
11
|
-
data_store[:key] =
|
12
|
+
|
13
|
+
data_store[:key] = 1
|
12
14
|
value.must_equal 1
|
13
15
|
end
|
14
16
|
|
15
17
|
it 'Reload' do
|
16
18
|
value = lazy_value :key
|
17
19
|
|
18
|
-
data_store[:key] =
|
20
|
+
data_store[:key] = 1
|
19
21
|
value.must_equal 1
|
20
22
|
|
21
|
-
data_store[:key] =
|
23
|
+
data_store[:key] = 2
|
22
24
|
value.must_equal 1
|
23
25
|
value.reload.must_equal 2
|
24
26
|
end
|
25
27
|
|
26
28
|
it 'Transparent proxy' do
|
27
29
|
value = lazy_value :key
|
28
|
-
data_store[:key] =
|
30
|
+
data_store[:key] = 1
|
29
31
|
value.must_equal 1
|
30
32
|
end
|
31
33
|
|
@@ -1,17 +1,15 @@
|
|
1
1
|
require 'minitest_helper'
|
2
|
-
require_relative './data_store_examples'
|
3
|
-
require_relative './lazy_value_examples'
|
4
2
|
|
5
3
|
describe Asynchronic::DataStore::Redis do
|
6
4
|
|
7
5
|
let(:data_store) { Asynchronic::DataStore::Redis.new :asynchronic_test }
|
8
6
|
|
9
|
-
after do
|
10
|
-
data_store.clear
|
11
|
-
end
|
12
|
-
|
13
7
|
include DataStoreExamples
|
14
8
|
|
9
|
+
describe 'LazyValue' do
|
10
|
+
include LazyValueExamples
|
11
|
+
end
|
12
|
+
|
15
13
|
it 'Safe deserialization' do
|
16
14
|
SampleClass = Class.new
|
17
15
|
|
@@ -24,8 +22,4 @@ describe Asynchronic::DataStore::Redis do
|
|
24
22
|
data_store[:instance].must_be_instance_of String
|
25
23
|
end
|
26
24
|
|
27
|
-
describe 'LazyValue' do
|
28
|
-
include LazyValueExamples
|
29
|
-
end
|
30
|
-
|
31
25
|
end
|
data/spec/expectations.rb
CHANGED
@@ -15,10 +15,10 @@ module MiniTest::Assertions
|
|
15
15
|
def assert_be_initialized(process)
|
16
16
|
process.must_be :pending?
|
17
17
|
process.wont_be :finalized?
|
18
|
-
|
18
|
+
|
19
19
|
process.processes.must_be_empty
|
20
20
|
process.error.must_be_nil
|
21
|
-
|
21
|
+
|
22
22
|
process.created_at.must_be_instance_of Time
|
23
23
|
process.queued_at.must_be_nil
|
24
24
|
process.started_at.must_be_nil
|
data/spec/facade_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Asynchronic, 'Facade' do
|
|
6
6
|
Asynchronic.environment.data_store.clear
|
7
7
|
Asynchronic.environment.queue_engine.clear
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it 'Default queue' do
|
11
11
|
Asynchronic.default_queue.must_equal :asynchronic_test
|
12
12
|
end
|
@@ -40,7 +40,7 @@ describe Asynchronic, 'Facade' do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'List processes' do
|
43
|
-
ids = 3.times.map do
|
43
|
+
ids = 3.times.map do
|
44
44
|
process = Asynchronic.environment.create_process SequentialJob
|
45
45
|
process.id
|
46
46
|
end
|
@@ -51,7 +51,7 @@ describe Asynchronic, 'Facade' do
|
|
51
51
|
|
52
52
|
it 'Enqueue' do
|
53
53
|
id = BasicJob.enqueue input: 100
|
54
|
-
|
54
|
+
|
55
55
|
Asynchronic.environment.tap do |env|
|
56
56
|
process = env.load_process id
|
57
57
|
process.type.must_equal BasicJob
|
data/spec/jobs.rb
CHANGED
@@ -9,8 +9,8 @@ class SequentialJob < Asynchronic::Job
|
|
9
9
|
|
10
10
|
def call
|
11
11
|
async Step1, input: params[:input]
|
12
|
-
|
13
|
-
async Step2, dependency: Step1,
|
12
|
+
|
13
|
+
async Step2, dependency: Step1,
|
14
14
|
input: params[:input]
|
15
15
|
|
16
16
|
nil
|
@@ -32,7 +32,7 @@ end
|
|
32
32
|
|
33
33
|
|
34
34
|
class GraphJob < Asynchronic::Job
|
35
|
-
|
35
|
+
|
36
36
|
def call
|
37
37
|
async Sum, input: params[:input]
|
38
38
|
|
@@ -113,13 +113,13 @@ class AliasJob < Asynchronic::Job
|
|
113
113
|
def call
|
114
114
|
async Write, alias: :word_1,
|
115
115
|
text: 'Take'
|
116
|
-
|
117
|
-
async Write, alias: :word_2,
|
118
|
-
text: 'it',
|
116
|
+
|
117
|
+
async Write, alias: :word_2,
|
118
|
+
text: 'it',
|
119
119
|
prefix: result(:word_1)
|
120
|
-
|
121
|
-
async Write, alias: :word_3,
|
122
|
-
text: 'easy',
|
120
|
+
|
121
|
+
async Write, alias: :word_3,
|
122
|
+
text: 'easy',
|
123
123
|
prefix: result(:word_2)
|
124
124
|
|
125
125
|
result :word_3
|
@@ -402,4 +402,4 @@ class BeforeFinalizeExceptionOnAbortedJob < Asynchronic::Job
|
|
402
402
|
def before_finalize
|
403
403
|
raise 'Before finalize error'
|
404
404
|
end
|
405
|
-
end
|
405
|
+
end
|
data/spec/minitest_helper.rb
CHANGED
@@ -9,9 +9,11 @@ require 'expectations'
|
|
9
9
|
require 'timeout'
|
10
10
|
require 'pry-nav'
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
require_relative 'data_store/data_store_examples'
|
13
|
+
require_relative 'data_store/lazy_value_examples'
|
14
|
+
require_relative 'process/life_cycle_examples'
|
15
|
+
require_relative 'queue_engine/queue_engine_examples'
|
16
|
+
require_relative 'worker/worker_examples'
|
15
17
|
|
16
18
|
Asynchronic.logger.level = Logger::FATAL
|
17
19
|
|
@@ -20,13 +22,4 @@ class Minitest::Spec
|
|
20
22
|
Asynchronic.restore_default_configuration
|
21
23
|
Asynchronic.default_queue = :asynchronic_test
|
22
24
|
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module Asynchronic::DataStore::Helper
|
26
|
-
def dump
|
27
|
-
puts 'DataStore:'
|
28
|
-
each do |k,v|
|
29
|
-
puts "#{k}: #{v}"
|
30
|
-
end
|
31
|
-
end
|
32
25
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module LifeCycleExamples
|
2
|
-
|
2
|
+
|
3
|
+
extend Minitest::Spec::DSL
|
4
|
+
|
3
5
|
let(:env) { Asynchronic::Environment.new queue_engine, data_store, notifier }
|
4
6
|
|
5
7
|
let(:queue) { env.default_queue }
|
@@ -29,7 +31,7 @@ module LifeCycleExamples
|
|
29
31
|
|
30
32
|
process.must_have_connection_name
|
31
33
|
process.wont_be :dead?
|
32
|
-
|
34
|
+
|
33
35
|
process.send(:connected?).must_be_true
|
34
36
|
|
35
37
|
env.queue_engine.stub(:active_connections, ->() { raise 'Forced error' }) do
|
@@ -138,7 +140,7 @@ module LifeCycleExamples
|
|
138
140
|
process[GraphJob::Total].must_be_pending
|
139
141
|
process[GraphJob::Total].must_have_params '10%' => nil, '20%' => nil
|
140
142
|
queue.must_enqueued process[GraphJob::Sum]
|
141
|
-
|
143
|
+
|
142
144
|
execute queue
|
143
145
|
|
144
146
|
process.must_be_waiting
|
@@ -294,7 +296,7 @@ module LifeCycleExamples
|
|
294
296
|
process[:word_3].result.must_equal 'Take it easy'
|
295
297
|
queue.must_be_empty
|
296
298
|
end
|
297
|
-
|
299
|
+
|
298
300
|
it 'Custom queue' do
|
299
301
|
process = create CustomQueueJob, input: 'hello'
|
300
302
|
|
@@ -308,7 +310,7 @@ module LifeCycleExamples
|
|
308
310
|
|
309
311
|
process.must_be_queued
|
310
312
|
process.processes.must_be_empty
|
311
|
-
|
313
|
+
|
312
314
|
env.queue(:queue_1).must_enqueued process
|
313
315
|
env.queue(:queue_2).must_be_empty
|
314
316
|
env.queue(:queue_3).must_be_empty
|
@@ -318,7 +320,7 @@ module LifeCycleExamples
|
|
318
320
|
process.must_be_waiting
|
319
321
|
process[CustomQueueJob::Reverse].must_be_queued
|
320
322
|
process[CustomQueueJob::Reverse].must_have_params input: 'hello'
|
321
|
-
|
323
|
+
|
322
324
|
env.queue(:queue_1).must_be_empty
|
323
325
|
env.queue(:queue_2).must_enqueued process[CustomQueueJob::Reverse]
|
324
326
|
env.queue(:queue_3).must_be_empty
|
@@ -329,7 +331,7 @@ module LifeCycleExamples
|
|
329
331
|
process.result.must_equal 'olleh'
|
330
332
|
process[CustomQueueJob::Reverse].must_be_completed
|
331
333
|
process[CustomQueueJob::Reverse].result.must_equal 'olleh'
|
332
|
-
|
334
|
+
|
333
335
|
env.queue(:queue_1).must_be_empty
|
334
336
|
env.queue(:queue_2).must_be_empty
|
335
337
|
env.queue(:queue_3).must_be_empty
|
@@ -485,7 +487,7 @@ module LifeCycleExamples
|
|
485
487
|
|
486
488
|
it 'Data' do
|
487
489
|
process = create DataJob, input: 1
|
488
|
-
|
490
|
+
|
489
491
|
process.enqueue
|
490
492
|
execute queue
|
491
493
|
|
@@ -497,7 +499,7 @@ module LifeCycleExamples
|
|
497
499
|
it 'Nested job with error in child' do
|
498
500
|
process = create NestedJobWithErrorInChildJob
|
499
501
|
|
500
|
-
process.enqueue
|
502
|
+
process.enqueue
|
501
503
|
|
502
504
|
Timeout.timeout(1) do
|
503
505
|
until process.status == :aborted
|
@@ -511,17 +513,17 @@ module LifeCycleExamples
|
|
511
513
|
it 'Nested job with error in parent' do
|
512
514
|
process = create NestedJobWithErrorInParentJob
|
513
515
|
|
514
|
-
process.enqueue
|
516
|
+
process.enqueue
|
515
517
|
|
516
518
|
execute queue
|
517
|
-
|
519
|
+
|
518
520
|
process.real_error.must_equal "Error in parent"
|
519
521
|
end
|
520
522
|
|
521
523
|
it 'Abort queued After error' do
|
522
524
|
process = create AbortQueuedAfterErrorJob
|
523
525
|
|
524
|
-
process.enqueue
|
526
|
+
process.enqueue
|
525
527
|
|
526
528
|
execute queue
|
527
529
|
|
@@ -592,6 +594,7 @@ module LifeCycleExamples
|
|
592
594
|
'AbortQueuedAfterErrorJob::Child_4' => :aborted
|
593
595
|
|
594
596
|
process.real_error.must_equal 'Forced error'
|
597
|
+
process.processes[0].processes[1].error.message.must_equal Asynchronic::Process::AUTOMATIC_ABORTED_ERROR_MESSAGE
|
595
598
|
end
|
596
599
|
|
597
600
|
it 'Manual abort' do
|
@@ -601,27 +604,27 @@ module LifeCycleExamples
|
|
601
604
|
|
602
605
|
execute queue
|
603
606
|
|
604
|
-
process.full_status.must_equal 'NestedJob' => :waiting,
|
607
|
+
process.full_status.must_equal 'NestedJob' => :waiting,
|
605
608
|
'NestedJob::Level1' => :queued
|
606
609
|
|
607
610
|
execute queue
|
608
611
|
|
609
|
-
process.full_status.must_equal 'NestedJob' => :waiting,
|
610
|
-
'NestedJob::Level1' => :waiting,
|
612
|
+
process.full_status.must_equal 'NestedJob' => :waiting,
|
613
|
+
'NestedJob::Level1' => :waiting,
|
611
614
|
'NestedJob::Level1::Level2' => :queued
|
612
615
|
|
613
616
|
process.cancel!
|
614
617
|
|
615
618
|
process.real_error.must_equal Asynchronic::Process::CANCELED_ERROR_MESSAGE
|
616
619
|
|
617
|
-
process.full_status.must_equal 'NestedJob' => :aborted,
|
618
|
-
'NestedJob::Level1' => :waiting,
|
620
|
+
process.full_status.must_equal 'NestedJob' => :aborted,
|
621
|
+
'NestedJob::Level1' => :waiting,
|
619
622
|
'NestedJob::Level1::Level2' => :queued
|
620
623
|
|
621
624
|
execute queue
|
622
625
|
|
623
|
-
process.full_status.must_equal 'NestedJob' => :aborted,
|
624
|
-
'NestedJob::Level1' => :aborted,
|
626
|
+
process.full_status.must_equal 'NestedJob' => :aborted,
|
627
|
+
'NestedJob::Level1' => :aborted,
|
625
628
|
'NestedJob::Level1::Level2' => :aborted
|
626
629
|
end
|
627
630
|
|
@@ -649,7 +652,7 @@ module LifeCycleExamples
|
|
649
652
|
process_1 = create AliasJob
|
650
653
|
process_1.enqueue
|
651
654
|
4.times { execute queue }
|
652
|
-
|
655
|
+
|
653
656
|
process_2 = create AliasJob
|
654
657
|
process_2.enqueue
|
655
658
|
execute queue
|
@@ -669,7 +672,7 @@ module LifeCycleExamples
|
|
669
672
|
data_store.keys.select { |k| k.start_with? pid_3 }.count.must_equal 7
|
670
673
|
|
671
674
|
gc = Asynchronic::GarbageCollector.new env, 0.001
|
672
|
-
|
675
|
+
|
673
676
|
gc.add_condition('Finalized', &:finalized?)
|
674
677
|
gc.add_condition('Waiting', &:waiting?)
|
675
678
|
gc.add_condition('Exception') { raise 'Invalid condition' }
|
@@ -677,7 +680,7 @@ module LifeCycleExamples
|
|
677
680
|
gc.conditions_names.must_equal ['Finalized', 'Waiting', 'Exception']
|
678
681
|
|
679
682
|
gc.remove_condition 'Waiting'
|
680
|
-
|
683
|
+
|
681
684
|
gc.conditions_names.must_equal ['Finalized', 'Exception']
|
682
685
|
|
683
686
|
Thread.new do
|
@@ -762,5 +765,4 @@ module LifeCycleExamples
|
|
762
765
|
queue.must_be_empty
|
763
766
|
end
|
764
767
|
|
765
|
-
|
766
768
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
require 'minitest_helper'
|
2
|
-
require_relative './queue_engine_examples'
|
3
2
|
|
4
3
|
describe Asynchronic::QueueEngine::InMemory do
|
5
4
|
|
6
5
|
let(:engine) { Asynchronic::QueueEngine::InMemory.new }
|
7
|
-
let(:listener) { Asynchronic::QueueEngine::InMemory::Listener.new }
|
8
6
|
|
9
7
|
include QueueEngineExamples
|
10
|
-
|
8
|
+
|
11
9
|
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
require 'minitest_helper'
|
2
|
-
require_relative './queue_engine_examples'
|
3
2
|
|
4
3
|
describe Asynchronic::QueueEngine::Ost do
|
5
4
|
|
6
5
|
let(:engine) { Asynchronic::QueueEngine::Ost.new }
|
7
|
-
let(:listener) { Asynchronic::QueueEngine::Ost::Listener.new }
|
8
6
|
|
9
|
-
before do
|
10
|
-
engine.clear
|
11
|
-
end
|
12
|
-
|
13
7
|
include QueueEngineExamples
|
14
8
|
|
15
9
|
it 'Engine and queues use same redis connection' do
|
16
10
|
engine.redis.must_equal queue.redis
|
17
11
|
end
|
18
|
-
|
12
|
+
|
19
13
|
end
|
@@ -1,26 +1,34 @@
|
|
1
1
|
module QueueEngineExamples
|
2
|
-
|
2
|
+
|
3
|
+
extend Minitest::Spec::DSL
|
4
|
+
|
3
5
|
let(:queue) { engine[:test_queue] }
|
4
6
|
|
7
|
+
let(:listener) { engine.listener }
|
8
|
+
|
9
|
+
after do
|
10
|
+
engine.clear
|
11
|
+
end
|
12
|
+
|
5
13
|
it 'Engine' do
|
6
|
-
engine.
|
7
|
-
|
14
|
+
engine.queue_names.must_be_empty
|
15
|
+
|
8
16
|
queue = engine[:test_engine]
|
9
17
|
queue.must_be_instance_of engine.class.const_get(:Queue)
|
10
|
-
engine.
|
11
|
-
|
18
|
+
engine.queue_names.must_equal [:test_engine]
|
19
|
+
|
12
20
|
engine[:test_engine].must_equal queue
|
13
|
-
|
21
|
+
|
14
22
|
engine.clear
|
15
|
-
engine.
|
23
|
+
engine.queue_names.must_be_empty
|
16
24
|
end
|
17
25
|
|
18
26
|
it 'Queue (push/pop)' do
|
19
27
|
queue.must_be_empty
|
20
|
-
|
28
|
+
|
21
29
|
queue.push 'msg_1'
|
22
30
|
queue.push 'msg_2'
|
23
|
-
|
31
|
+
|
24
32
|
queue.size.must_equal 2
|
25
33
|
queue.to_a.must_equal %w(msg_1 msg_2)
|
26
34
|
|