asynchronic 2.0.1 → 3.0.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/asynchronic.gemspec +2 -0
- data/lib/asynchronic.rb +3 -1
- data/lib/asynchronic/environment.rb +3 -3
- data/lib/asynchronic/garbage_collector.rb +2 -0
- data/lib/asynchronic/notifier/broadcaster.rb +30 -0
- data/lib/asynchronic/notifier/in_memory.rb +33 -0
- data/lib/asynchronic/process.rb +9 -0
- data/lib/asynchronic/version.rb +1 -1
- data/spec/data_store/lazy_value_examples.rb +0 -1
- data/spec/jobs.rb +1 -1
- data/spec/minitest_helper.rb +1 -0
- data/spec/process/life_cycle_examples.rb +82 -42
- data/spec/process/life_cycle_in_memory_spec.rb +1 -0
- data/spec/process/life_cycle_redis_spec.rb +1 -0
- data/spec/worker/in_memory_spec.rb +1 -0
- data/spec/worker/redis_spec.rb +1 -0
- data/spec/worker/worker_examples.rb +1 -1
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe064d93526974fae713afcd2d5fc4730cb65b94
|
4
|
+
data.tar.gz: f6ca2831a8d78323370116397d1cbb9d48c66837
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6668033166027a2d54aca7b094f8f90642f4b180f01299e99099a62b47f3dffd871799773248c3ad0bb3a4127885029234cda953265782926b685a5596743b3
|
7
|
+
data.tar.gz: 86da5ba9d7207fae1d6f01f77f433f8ed7e3b6d6e64e3bec177755088ee0c844f5c8a768f942c905ce730d9ea1d6dfcf5caee4db1a83b20bbf4a7727a721ed04
|
data/asynchronic.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'ost', '~> 1.0'
|
22
|
+
spec.add_dependency 'broadcaster', '~> 1.0'
|
22
23
|
spec.add_dependency 'class_config', '~> 0.0'
|
23
24
|
spec.add_dependency 'transparent_proxy', '~> 0.0'
|
24
25
|
spec.add_dependency 'multi_require', '~> 1.0'
|
@@ -27,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
27
28
|
spec.add_development_dependency 'rake', '~> 11.0'
|
28
29
|
spec.add_development_dependency 'minitest', '~> 5.0', '< 5.11'
|
29
30
|
spec.add_development_dependency 'minitest-great_expectations', '~> 0.0'
|
31
|
+
spec.add_development_dependency 'minitest-stub_any_instance', '~> 1.0'
|
30
32
|
spec.add_development_dependency 'minitest-colorin', '~> 0.1'
|
31
33
|
spec.add_development_dependency 'minitest-line', '~> 0.6'
|
32
34
|
spec.add_development_dependency 'simplecov', '~> 0.12'
|
data/lib/asynchronic.rb
CHANGED
@@ -2,6 +2,7 @@ require 'forwardable'
|
|
2
2
|
require 'securerandom'
|
3
3
|
require 'ost'
|
4
4
|
require 'redic'
|
5
|
+
require 'broadcaster'
|
5
6
|
require 'class_config'
|
6
7
|
require 'transparent_proxy'
|
7
8
|
require 'logger'
|
@@ -18,6 +19,7 @@ module Asynchronic
|
|
18
19
|
attr_config :default_queue, :asynchronic
|
19
20
|
attr_config :queue_engine, QueueEngine::InMemory.new
|
20
21
|
attr_config :data_store, DataStore::InMemory.new
|
22
|
+
attr_config :notifier, Notifier::InMemory.new
|
21
23
|
attr_config :logger, Logger.new($stdout)
|
22
24
|
attr_config :retry_timeout, 30
|
23
25
|
attr_config :garbage_collector_timeout, 30
|
@@ -26,7 +28,7 @@ module Asynchronic
|
|
26
28
|
attr_config :connection_name, "HOST=#{Socket.gethostname},PID=#{::Process.pid}"
|
27
29
|
|
28
30
|
def self.environment
|
29
|
-
Environment.new queue_engine, data_store
|
31
|
+
Environment.new queue_engine, data_store, notifier
|
30
32
|
end
|
31
33
|
|
32
34
|
def self.[](pid)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Asynchronic
|
2
2
|
class Environment
|
3
3
|
|
4
|
-
attr_reader :queue_engine
|
5
|
-
attr_reader :data_store
|
4
|
+
attr_reader :queue_engine, :data_store, :notifier
|
6
5
|
|
7
|
-
def initialize(queue_engine, data_store)
|
6
|
+
def initialize(queue_engine, data_store, notifier)
|
8
7
|
@queue_engine = queue_engine
|
9
8
|
@data_store = data_store
|
9
|
+
@notifier = notifier
|
10
10
|
end
|
11
11
|
|
12
12
|
def queue(name)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Asynchronic
|
2
|
+
module Notifier
|
3
|
+
class Broadcaster
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
options[:logger] ||= Asynchronic.logger
|
7
|
+
@broadcaster = ::Broadcaster.new options
|
8
|
+
end
|
9
|
+
|
10
|
+
def publish(pid, event, data=nil)
|
11
|
+
@broadcaster.publish DataStore::Key[pid][event], data
|
12
|
+
end
|
13
|
+
|
14
|
+
def subscribe(pid, event, &block)
|
15
|
+
@broadcaster.subscribe DataStore::Key[pid][event] do |data|
|
16
|
+
block.call data
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def unsubscribe(subscription_id)
|
21
|
+
@broadcaster.unsubscribe subscription_id
|
22
|
+
end
|
23
|
+
|
24
|
+
def unsubscribe_all
|
25
|
+
@broadcaster.unsubscribe_all
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Asynchronic
|
2
|
+
module Notifier
|
3
|
+
class InMemory
|
4
|
+
|
5
|
+
def publish(pid, event, data=nil)
|
6
|
+
subscriptions[DataStore::Key[pid][event]].each_value do |block|
|
7
|
+
block.call data
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def subscribe(pid, event, &block)
|
12
|
+
SecureRandom.uuid.tap do |subscription_id|
|
13
|
+
subscriptions[DataStore::Key[pid][event]][subscription_id] = block
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def unsubscribe(subscription_id)
|
18
|
+
subscriptions.each_value { |s| s.delete subscription_id }
|
19
|
+
end
|
20
|
+
|
21
|
+
def unsubscribe_all
|
22
|
+
subscriptions.clear
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def subscriptions
|
28
|
+
@subscriptions ||= Hash.new { |h,k| h[k] = {} }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/asynchronic/process.rb
CHANGED
@@ -14,6 +14,7 @@ module Asynchronic
|
|
14
14
|
ATTRIBUTE_NAMES = [:type, :name, :queue, :status, :dependencies, :data, :result, :error, :connection_name] | TIME_TRACKING_MAP.values.uniq
|
15
15
|
|
16
16
|
CANCELED_ERROR_MESSAGE = 'Canceled'
|
17
|
+
DEAD_ERROR_MESSAGE = 'Process connection broken'
|
17
18
|
|
18
19
|
attr_reader :id
|
19
20
|
|
@@ -51,6 +52,10 @@ module Asynchronic
|
|
51
52
|
(running? && !connected?) || processes.any?(&:dead?)
|
52
53
|
end
|
53
54
|
|
55
|
+
def abort_if_dead
|
56
|
+
abort! DEAD_ERROR_MESSAGE if dead?
|
57
|
+
end
|
58
|
+
|
54
59
|
def destroy
|
55
60
|
data_store.delete_cascade
|
56
61
|
end
|
@@ -190,8 +195,12 @@ module Asynchronic
|
|
190
195
|
|
191
196
|
def status=(status)
|
192
197
|
Asynchronic.logger.info('Asynchronic') { "#{status.to_s.capitalize} #{type} (#{id})" }
|
198
|
+
|
193
199
|
data_store[:status] = status
|
194
200
|
data_store[TIME_TRACKING_MAP[status]] = Time.now if TIME_TRACKING_MAP.key? status
|
201
|
+
|
202
|
+
environment.notifier.publish id, :status_changed, status
|
203
|
+
environment.notifier.publish id, :finalized if finalized?
|
195
204
|
end
|
196
205
|
|
197
206
|
STATUSES.each do |status|
|
data/lib/asynchronic/version.rb
CHANGED
data/spec/jobs.rb
CHANGED
data/spec/minitest_helper.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
module LifeCycleExamples
|
2
2
|
|
3
|
-
let(:env) { Asynchronic::Environment.new queue_engine, data_store }
|
3
|
+
let(:env) { Asynchronic::Environment.new queue_engine, data_store, notifier }
|
4
4
|
|
5
5
|
let(:queue) { env.default_queue }
|
6
6
|
|
7
7
|
after do
|
8
8
|
data_store.clear
|
9
9
|
queue_engine.clear
|
10
|
+
notifier.unsubscribe_all
|
10
11
|
end
|
11
12
|
|
12
13
|
def create(type, params={})
|
@@ -17,10 +18,41 @@ module LifeCycleExamples
|
|
17
18
|
|
18
19
|
def execute(queue)
|
19
20
|
process = env.load_process(queue.pop)
|
21
|
+
|
22
|
+
events = []
|
23
|
+
status_changed_id = notifier.subscribe(process.id, :status_changed) { |status| events << status }
|
24
|
+
|
25
|
+
is_finalized = false
|
26
|
+
finalized_id = notifier.subscribe(process.id, :finalized) { is_finalized = true }
|
27
|
+
|
20
28
|
process.execute
|
29
|
+
|
21
30
|
process.must_have_connection_name
|
22
31
|
process.wont_be :dead?
|
23
32
|
process.send(:connected?).must_be_true
|
33
|
+
|
34
|
+
with_retries do
|
35
|
+
events.last.must_equal process.status
|
36
|
+
process.finalized?.must_equal is_finalized
|
37
|
+
end
|
38
|
+
|
39
|
+
notifier.unsubscribe status_changed_id
|
40
|
+
notifier.unsubscribe finalized_id
|
41
|
+
|
42
|
+
status = process.status
|
43
|
+
process.abort_if_dead
|
44
|
+
process.status.must_equal status
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_retries(&block)
|
48
|
+
Timeout.timeout(3) do
|
49
|
+
begin
|
50
|
+
block.call
|
51
|
+
rescue Minitest::Assertion
|
52
|
+
sleep 0.001
|
53
|
+
retry
|
54
|
+
end
|
55
|
+
end
|
24
56
|
end
|
25
57
|
|
26
58
|
it 'Basic' do
|
@@ -481,78 +513,78 @@ module LifeCycleExamples
|
|
481
513
|
process.real_error.must_equal "Error in parent"
|
482
514
|
end
|
483
515
|
|
484
|
-
it 'Abort queued
|
485
|
-
process = create
|
516
|
+
it 'Abort queued After error' do
|
517
|
+
process = create AbortQueuedAfterErrorJob
|
486
518
|
|
487
519
|
process.enqueue
|
488
520
|
|
489
521
|
execute queue
|
490
522
|
|
491
|
-
process.full_status.must_equal '
|
492
|
-
'
|
493
|
-
'
|
494
|
-
'
|
495
|
-
'
|
523
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :waiting,
|
524
|
+
'AbortQueuedAfterErrorJob::Child_1' => :queued,
|
525
|
+
'AbortQueuedAfterErrorJob::Child_2' => :queued,
|
526
|
+
'AbortQueuedAfterErrorJob::Child_3' => :queued,
|
527
|
+
'AbortQueuedAfterErrorJob::Child_4' => :queued
|
496
528
|
|
497
529
|
execute queue
|
498
530
|
|
499
|
-
process.full_status.must_equal '
|
500
|
-
'
|
531
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :waiting,
|
532
|
+
'AbortQueuedAfterErrorJob::Child_1' => :waiting,
|
501
533
|
'Child_1_1' => :queued,
|
502
534
|
'Child_1_2' => :queued,
|
503
|
-
'
|
504
|
-
'
|
505
|
-
'
|
535
|
+
'AbortQueuedAfterErrorJob::Child_2' => :queued,
|
536
|
+
'AbortQueuedAfterErrorJob::Child_3' => :queued,
|
537
|
+
'AbortQueuedAfterErrorJob::Child_4' => :queued
|
506
538
|
|
507
539
|
execute queue
|
508
540
|
|
509
|
-
process.full_status.must_equal '
|
510
|
-
'
|
541
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :waiting,
|
542
|
+
'AbortQueuedAfterErrorJob::Child_1' => :waiting,
|
511
543
|
'Child_1_1' => :queued,
|
512
544
|
'Child_1_2' => :queued,
|
513
|
-
'
|
514
|
-
'
|
515
|
-
'
|
545
|
+
'AbortQueuedAfterErrorJob::Child_2' => :completed,
|
546
|
+
'AbortQueuedAfterErrorJob::Child_3' => :queued,
|
547
|
+
'AbortQueuedAfterErrorJob::Child_4' => :queued
|
516
548
|
|
517
549
|
execute queue
|
518
550
|
|
519
|
-
process.full_status.must_equal '
|
520
|
-
'
|
551
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :aborted,
|
552
|
+
'AbortQueuedAfterErrorJob::Child_1' => :waiting,
|
521
553
|
'Child_1_1' => :queued,
|
522
554
|
'Child_1_2' => :queued,
|
523
|
-
'
|
524
|
-
'
|
525
|
-
'
|
555
|
+
'AbortQueuedAfterErrorJob::Child_2' => :completed,
|
556
|
+
'AbortQueuedAfterErrorJob::Child_3' => :aborted,
|
557
|
+
'AbortQueuedAfterErrorJob::Child_4' => :queued
|
526
558
|
|
527
559
|
execute queue
|
528
560
|
|
529
|
-
process.full_status.must_equal '
|
530
|
-
'
|
561
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :aborted,
|
562
|
+
'AbortQueuedAfterErrorJob::Child_1' => :waiting,
|
531
563
|
'Child_1_1' => :queued,
|
532
564
|
'Child_1_2' => :queued,
|
533
|
-
'
|
534
|
-
'
|
535
|
-
'
|
565
|
+
'AbortQueuedAfterErrorJob::Child_2' => :completed,
|
566
|
+
'AbortQueuedAfterErrorJob::Child_3' => :aborted,
|
567
|
+
'AbortQueuedAfterErrorJob::Child_4' => :aborted
|
536
568
|
|
537
569
|
execute queue
|
538
570
|
|
539
|
-
process.full_status.must_equal '
|
540
|
-
'
|
571
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :aborted,
|
572
|
+
'AbortQueuedAfterErrorJob::Child_1' => :aborted,
|
541
573
|
'Child_1_1' => :aborted,
|
542
574
|
'Child_1_2' => :queued,
|
543
|
-
'
|
544
|
-
'
|
545
|
-
'
|
575
|
+
'AbortQueuedAfterErrorJob::Child_2' => :completed,
|
576
|
+
'AbortQueuedAfterErrorJob::Child_3' => :aborted,
|
577
|
+
'AbortQueuedAfterErrorJob::Child_4' => :aborted
|
546
578
|
|
547
579
|
execute queue
|
548
580
|
|
549
|
-
process.full_status.must_equal '
|
550
|
-
'
|
581
|
+
process.full_status.must_equal 'AbortQueuedAfterErrorJob' => :aborted,
|
582
|
+
'AbortQueuedAfterErrorJob::Child_1' => :aborted,
|
551
583
|
'Child_1_1' => :aborted,
|
552
584
|
'Child_1_2' => :aborted,
|
553
|
-
'
|
554
|
-
'
|
555
|
-
'
|
585
|
+
'AbortQueuedAfterErrorJob::Child_2' => :completed,
|
586
|
+
'AbortQueuedAfterErrorJob::Child_3' => :aborted,
|
587
|
+
'AbortQueuedAfterErrorJob::Child_4' => :aborted
|
556
588
|
|
557
589
|
process.real_error.must_equal 'Forced error'
|
558
590
|
end
|
@@ -617,36 +649,44 @@ module LifeCycleExamples
|
|
617
649
|
process_2.enqueue
|
618
650
|
execute queue
|
619
651
|
|
652
|
+
process_3 = create BasicJob
|
653
|
+
|
620
654
|
pid_1 = process_1.id
|
621
655
|
pid_2 = process_2.id
|
656
|
+
pid_3 = process_3.id
|
622
657
|
|
623
658
|
process_1.must_be_completed
|
624
659
|
process_2.must_be_waiting
|
660
|
+
process_3.must_be_pending
|
625
661
|
|
626
662
|
data_store.keys.select { |k| k.start_with? pid_1 }.count.must_equal 53
|
627
663
|
data_store.keys.select { |k| k.start_with? pid_2 }.count.must_equal 38
|
664
|
+
data_store.keys.select { |k| k.start_with? pid_3 }.count.must_equal 7
|
628
665
|
|
629
666
|
gc = Asynchronic::GarbageCollector.new env, 0.001
|
630
667
|
|
631
|
-
gc.add_condition('
|
668
|
+
gc.add_condition('Finalized', &:finalized?)
|
632
669
|
gc.add_condition('Waiting', &:waiting?)
|
633
670
|
gc.add_condition('Exception') { raise 'Invalid condition' }
|
634
671
|
|
635
|
-
gc.conditions_names.must_equal ['
|
672
|
+
gc.conditions_names.must_equal ['Finalized', 'Waiting', 'Exception']
|
636
673
|
|
637
674
|
gc.remove_condition 'Waiting'
|
638
675
|
|
639
|
-
gc.conditions_names.must_equal ['
|
676
|
+
gc.conditions_names.must_equal ['Finalized', 'Exception']
|
640
677
|
|
641
678
|
Thread.new do
|
642
679
|
sleep 0.01
|
643
680
|
gc.stop
|
644
681
|
end
|
645
682
|
|
646
|
-
|
683
|
+
Asynchronic::Process.stub_any_instance(:dead?, -> { id == pid_3 }) do
|
684
|
+
gc.start
|
685
|
+
end
|
647
686
|
|
648
687
|
data_store.keys.select { |k| k.start_with? pid_1 }.count.must_equal 0
|
649
688
|
data_store.keys.select { |k| k.start_with? pid_2 }.count.must_equal 38
|
689
|
+
data_store.keys.select { |k| k.start_with? pid_3 }.count.must_equal 0
|
650
690
|
end
|
651
691
|
|
652
692
|
it 'Before finalize hook when completed' do
|
@@ -5,6 +5,7 @@ describe Asynchronic::Process, 'Life cycle - InMemory' do
|
|
5
5
|
|
6
6
|
let(:queue_engine) { Asynchronic::QueueEngine::InMemory.new }
|
7
7
|
let(:data_store) { Asynchronic::DataStore::InMemory.new }
|
8
|
+
let(:notifier) { Asynchronic::Notifier::InMemory.new }
|
8
9
|
|
9
10
|
include LifeCycleExamples
|
10
11
|
|
@@ -5,6 +5,7 @@ describe Asynchronic::Process, 'Life cycle - Redis' do
|
|
5
5
|
|
6
6
|
let(:queue_engine) { Asynchronic::QueueEngine::Ost.new }
|
7
7
|
let(:data_store) { Asynchronic::DataStore::Redis.new :asynchronic_test }
|
8
|
+
let(:notifier) { Asynchronic::Notifier::Broadcaster.new }
|
8
9
|
|
9
10
|
include LifeCycleExamples
|
10
11
|
|
data/spec/worker/redis_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe Asynchronic::Worker, 'Redis' do
|
|
5
5
|
|
6
6
|
let(:queue_engine) { Asynchronic::QueueEngine::Ost.new }
|
7
7
|
let(:data_store) { Asynchronic::DataStore::Redis.new :asynchronic_test}
|
8
|
+
let(:notifier) { Asynchronic::Notifier::Broadcaster.new }
|
8
9
|
|
9
10
|
after do
|
10
11
|
data_store.clear
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asynchronic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ost
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: broadcaster
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: class_config
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,6 +142,20 @@ dependencies:
|
|
128
142
|
- - "~>"
|
129
143
|
- !ruby/object:Gem::Version
|
130
144
|
version: '0.0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: minitest-stub_any_instance
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '1.0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - "~>"
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '1.0'
|
131
159
|
- !ruby/object:Gem::Dependency
|
132
160
|
name: minitest-colorin
|
133
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -229,6 +257,8 @@ files:
|
|
229
257
|
- lib/asynchronic/error.rb
|
230
258
|
- lib/asynchronic/garbage_collector.rb
|
231
259
|
- lib/asynchronic/job.rb
|
260
|
+
- lib/asynchronic/notifier/broadcaster.rb
|
261
|
+
- lib/asynchronic/notifier/in_memory.rb
|
232
262
|
- lib/asynchronic/process.rb
|
233
263
|
- lib/asynchronic/queue_engine/in_memory.rb
|
234
264
|
- lib/asynchronic/queue_engine/ost.rb
|