activejob-locking 0.5.1 → 0.6.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 +5 -5
- data/Gemfile +10 -10
- data/LICENSE +20 -20
- data/Rakefile +20 -20
- data/lib/activejob/locking/base.rb +50 -50
- data/lib/activejob/locking/options.rb +72 -72
- data/lib/activejob/locking/serialized.rb +23 -23
- data/lib/activejob/locking/unique.rb +25 -25
- data/test/serialized_tests.rb +62 -62
- data/test/test_helper.rb +19 -19
- data/test/test_serialized_memory.rb +10 -10
- data/test/test_serialized_redis_semaphore.rb +11 -11
- data/test/test_serialized_redlock.rb +13 -13
- data/test/test_serialized_suo_redis.rb +11 -11
- data/test/test_unique_memory.rb +12 -12
- data/test/test_unique_redis_semaphore.rb +11 -11
- data/test/test_unique_redlock.rb +13 -13
- data/test/test_unique_suo_redis.rb +11 -11
- data/test/unique_tests.rb +99 -99
- metadata +11 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be52bd8f794ad9f15a6a66dfda55233ee68348f1a67a84985586215a8ad257a2
|
4
|
+
data.tar.gz: 24b93c41cff4548b2aa6fd128cc67ec62ea1da329f1f2dae4fa0bac2418e23b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9755a392e33e9bba7ce7ac809d2b6ff82029fe62ed17cfdc90d6cde3a0b389e6d95588aac6d0d957fbd91c1ea8f067038d16e68ae39ea6c6d5c567213c6407fb
|
7
|
+
data.tar.gz: 547262df7cae0c84637fe012fa64e253caf71fbf1586ca4393960af51ce44c4baa97377d25fbdf0d128d558ba738bc870f446e09a899d2a76317bf37f1da2c42
|
data/Gemfile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gem 'activejob', :require => 'active_job'
|
4
|
-
|
5
|
-
group :test do
|
6
|
-
gem 'minitest'
|
7
|
-
gem 'redis-semaphore'
|
8
|
-
gem 'redlock'
|
9
|
-
gem 'suo'
|
10
|
-
end
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activejob', :require => 'active_job'
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
gem 'minitest'
|
7
|
+
gem 'redis-semaphore'
|
8
|
+
gem 'redlock'
|
9
|
+
gem 'suo'
|
10
|
+
end
|
data/LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
Copyright (c) 2017 Charlie Savage
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
Software), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
Copyright (c) 2017 Charlie Savage
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
Software), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'rake/clean'
|
4
|
-
require 'rake/testtask'
|
5
|
-
require 'rubygems/package_task'
|
6
|
-
|
7
|
-
# Set global variable so other tasks can access them
|
8
|
-
::PROJECT_ROOT = File.expand_path(".")
|
9
|
-
::GEM_NAME = 'activejob-locking'
|
10
|
-
|
11
|
-
# Read the spec file
|
12
|
-
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
13
|
-
|
14
|
-
# Setup Rake tasks for managing the gem
|
15
|
-
Gem::PackageTask.new(spec).define
|
16
|
-
|
17
|
-
desc 'Run unit tests.'
|
18
|
-
Rake::TestTask.new(:test) do |task|
|
19
|
-
task.test_files = FileList['test/test_*.rb']
|
20
|
-
task.verbose = true
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
|
7
|
+
# Set global variable so other tasks can access them
|
8
|
+
::PROJECT_ROOT = File.expand_path(".")
|
9
|
+
::GEM_NAME = 'activejob-locking'
|
10
|
+
|
11
|
+
# Read the spec file
|
12
|
+
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
13
|
+
|
14
|
+
# Setup Rake tasks for managing the gem
|
15
|
+
Gem::PackageTask.new(spec).define
|
16
|
+
|
17
|
+
desc 'Run unit tests.'
|
18
|
+
Rake::TestTask.new(:test) do |task|
|
19
|
+
task.test_files = FileList['test/test_*.rb']
|
20
|
+
task.verbose = true
|
21
21
|
end
|
@@ -1,51 +1,51 @@
|
|
1
|
-
module ActiveJob
|
2
|
-
module Locking
|
3
|
-
module Base
|
4
|
-
extend ::ActiveSupport::Concern
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def lock_options
|
8
|
-
@lock_options ||= ActiveJob::Locking::Options.new
|
9
|
-
end
|
10
|
-
delegate :adapter, :enqueue_time, :hosts, :lock_time, :lock_acquire_time, :adapter_options, to: :lock_options
|
11
|
-
delegate :adapter=, :enqueue_time=, :hosts=, :lock_time=, :lock_acquire_time=, :adapter_options=, to: :lock_options
|
12
|
-
end
|
13
|
-
|
14
|
-
included do
|
15
|
-
# We need to serialize the lock token that some gems create because it could be released in a different process
|
16
|
-
def serialize
|
17
|
-
result = super
|
18
|
-
result['lock_token'] = self.adapter.lock_token
|
19
|
-
result
|
20
|
-
end
|
21
|
-
|
22
|
-
def deserialize(job_data)
|
23
|
-
super
|
24
|
-
self.adapter.lock_token = job_data['lock_token']
|
25
|
-
end
|
26
|
-
|
27
|
-
def lock_key(*args)
|
28
|
-
[self.class.name, serialize_arguments(self.arguments)].join('/')
|
29
|
-
end
|
30
|
-
|
31
|
-
def adapter
|
32
|
-
@adapter ||= begin
|
33
|
-
# Make sure arguments are deserialized so calling lock key is safe
|
34
|
-
deserialize_arguments_if_needed
|
35
|
-
|
36
|
-
# Merge local and global options
|
37
|
-
merged_options = ActiveJob::Locking.options.dup.merge(self.class.lock_options)
|
38
|
-
|
39
|
-
# Get the key
|
40
|
-
base_key = self.lock_key(*self.arguments)
|
41
|
-
key = "activejoblocking:#{base_key}"
|
42
|
-
|
43
|
-
# Remember the lock might be acquired in one process and released in another
|
44
|
-
merged_options.adapter.new(key, merged_options)
|
45
|
-
end
|
46
|
-
@adapter
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
1
|
+
module ActiveJob
|
2
|
+
module Locking
|
3
|
+
module Base
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def lock_options
|
8
|
+
@lock_options ||= ActiveJob::Locking::Options.new
|
9
|
+
end
|
10
|
+
delegate :adapter, :enqueue_time, :hosts, :lock_time, :lock_acquire_time, :adapter_options, to: :lock_options
|
11
|
+
delegate :adapter=, :enqueue_time=, :hosts=, :lock_time=, :lock_acquire_time=, :adapter_options=, to: :lock_options
|
12
|
+
end
|
13
|
+
|
14
|
+
included do
|
15
|
+
# We need to serialize the lock token that some gems create because it could be released in a different process
|
16
|
+
def serialize
|
17
|
+
result = super
|
18
|
+
result['lock_token'] = self.adapter.lock_token
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
def deserialize(job_data)
|
23
|
+
super
|
24
|
+
self.adapter.lock_token = job_data['lock_token']
|
25
|
+
end
|
26
|
+
|
27
|
+
def lock_key(*args)
|
28
|
+
[self.class.name, serialize_arguments(self.arguments)].join('/')
|
29
|
+
end
|
30
|
+
|
31
|
+
def adapter
|
32
|
+
@adapter ||= begin
|
33
|
+
# Make sure arguments are deserialized so calling lock key is safe
|
34
|
+
deserialize_arguments_if_needed
|
35
|
+
|
36
|
+
# Merge local and global options
|
37
|
+
merged_options = ActiveJob::Locking.options.dup.merge(self.class.lock_options)
|
38
|
+
|
39
|
+
# Get the key
|
40
|
+
base_key = self.lock_key(*self.arguments)
|
41
|
+
key = "activejoblocking:#{base_key}"
|
42
|
+
|
43
|
+
# Remember the lock might be acquired in one process and released in another
|
44
|
+
merged_options.adapter.new(key, merged_options)
|
45
|
+
end
|
46
|
+
@adapter
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
51
|
end
|
@@ -1,73 +1,73 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
|
-
module ActiveJob
|
4
|
-
module Locking
|
5
|
-
class Options
|
6
|
-
attr_accessor :adapter
|
7
|
-
attr_accessor :hosts
|
8
|
-
attr_accessor :lock_time
|
9
|
-
attr_accessor :lock_acquire_time
|
10
|
-
attr_accessor :enqueue_time
|
11
|
-
attr_accessor :adapter_options
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
@adapter = options[:adapter]
|
15
|
-
@hosts = options[:hosts]
|
16
|
-
@enqueue_time = options[:enqueue_time]
|
17
|
-
@lock_time = options[:lock_time]
|
18
|
-
@lock_acquire_time = options[:lock_acquire_time]
|
19
|
-
@adapter_options = options[:adapter_options]
|
20
|
-
end
|
21
|
-
|
22
|
-
def enqueue_time=(value)
|
23
|
-
case value
|
24
|
-
when NilClass
|
25
|
-
raise(ArgumentError, 'Enqueue time must be set')
|
26
|
-
when ActiveSupport::Duration
|
27
|
-
@enqueue_time = value.value
|
28
|
-
when 0
|
29
|
-
raise(ArgumentError, 'Enqueue time must be greater than zero')
|
30
|
-
else
|
31
|
-
@enqueue_time = value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def lock_time=(value)
|
36
|
-
case value
|
37
|
-
when NilClass
|
38
|
-
raise(ArgumentError, 'Lock time must be set')
|
39
|
-
when ActiveSupport::Duration
|
40
|
-
@lock_time = value.value
|
41
|
-
when 0
|
42
|
-
raise(ArgumentError, 'Lock time must be greater than zero')
|
43
|
-
else
|
44
|
-
@lock_time = value
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def lock_acquire_time=(value)
|
49
|
-
case value
|
50
|
-
when NilClass
|
51
|
-
raise(ArgumentError, 'Lock acquire time must be set')
|
52
|
-
when ActiveSupport::Duration
|
53
|
-
@lock_acquire_time = value.value
|
54
|
-
when 0
|
55
|
-
raise(ArgumentError, 'Lock acquire time must be greater than zero')
|
56
|
-
else
|
57
|
-
@lock_acquire_time = value
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def merge(other)
|
62
|
-
result = self.dup
|
63
|
-
result.adapter = other.adapter if other.adapter
|
64
|
-
result.hosts = other.hosts if other.hosts
|
65
|
-
result.enqueue_time = other.enqueue_time if other.enqueue_time
|
66
|
-
result.lock_time = other.lock_time if other.lock_time
|
67
|
-
result.lock_acquire_time = other.lock_acquire_time if other.lock_acquire_time
|
68
|
-
result.adapter_options = other.adapter_options if other.adapter_options
|
69
|
-
result
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module Locking
|
5
|
+
class Options
|
6
|
+
attr_accessor :adapter
|
7
|
+
attr_accessor :hosts
|
8
|
+
attr_accessor :lock_time
|
9
|
+
attr_accessor :lock_acquire_time
|
10
|
+
attr_accessor :enqueue_time
|
11
|
+
attr_accessor :adapter_options
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@adapter = options[:adapter]
|
15
|
+
@hosts = options[:hosts]
|
16
|
+
@enqueue_time = options[:enqueue_time]
|
17
|
+
@lock_time = options[:lock_time]
|
18
|
+
@lock_acquire_time = options[:lock_acquire_time]
|
19
|
+
@adapter_options = options[:adapter_options]
|
20
|
+
end
|
21
|
+
|
22
|
+
def enqueue_time=(value)
|
23
|
+
case value
|
24
|
+
when NilClass
|
25
|
+
raise(ArgumentError, 'Enqueue time must be set')
|
26
|
+
when ActiveSupport::Duration
|
27
|
+
@enqueue_time = value.value
|
28
|
+
when 0
|
29
|
+
raise(ArgumentError, 'Enqueue time must be greater than zero')
|
30
|
+
else
|
31
|
+
@enqueue_time = value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def lock_time=(value)
|
36
|
+
case value
|
37
|
+
when NilClass
|
38
|
+
raise(ArgumentError, 'Lock time must be set')
|
39
|
+
when ActiveSupport::Duration
|
40
|
+
@lock_time = value.value
|
41
|
+
when 0
|
42
|
+
raise(ArgumentError, 'Lock time must be greater than zero')
|
43
|
+
else
|
44
|
+
@lock_time = value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def lock_acquire_time=(value)
|
49
|
+
case value
|
50
|
+
when NilClass
|
51
|
+
raise(ArgumentError, 'Lock acquire time must be set')
|
52
|
+
when ActiveSupport::Duration
|
53
|
+
@lock_acquire_time = value.value
|
54
|
+
when 0
|
55
|
+
raise(ArgumentError, 'Lock acquire time must be greater than zero')
|
56
|
+
else
|
57
|
+
@lock_acquire_time = value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def merge(other)
|
62
|
+
result = self.dup
|
63
|
+
result.adapter = other.adapter if other.adapter
|
64
|
+
result.hosts = other.hosts if other.hosts
|
65
|
+
result.enqueue_time = other.enqueue_time if other.enqueue_time
|
66
|
+
result.lock_time = other.lock_time if other.lock_time
|
67
|
+
result.lock_acquire_time = other.lock_acquire_time if other.lock_acquire_time
|
68
|
+
result.adapter_options = other.adapter_options if other.adapter_options
|
69
|
+
result
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
73
|
end
|
@@ -1,23 +1,23 @@
|
|
1
|
-
module ActiveJob
|
2
|
-
module Locking
|
3
|
-
module Serialized
|
4
|
-
extend ::ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
include ::ActiveJob::Locking::Base
|
8
|
-
|
9
|
-
around_perform do |job, block|
|
10
|
-
if job.adapter.lock
|
11
|
-
begin
|
12
|
-
block.call
|
13
|
-
ensure
|
14
|
-
job.adapter.unlock
|
15
|
-
end
|
16
|
-
else
|
17
|
-
job.class.set(wait: job.adapter.options.enqueue_time).perform_later(*job.arguments)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
1
|
+
module ActiveJob
|
2
|
+
module Locking
|
3
|
+
module Serialized
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include ::ActiveJob::Locking::Base
|
8
|
+
|
9
|
+
around_perform do |job, block|
|
10
|
+
if job.adapter.lock
|
11
|
+
begin
|
12
|
+
block.call
|
13
|
+
ensure
|
14
|
+
job.adapter.unlock
|
15
|
+
end
|
16
|
+
else
|
17
|
+
job.class.set(wait: job.adapter.options.enqueue_time).perform_later(*job.arguments)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,25 +1,25 @@
|
|
1
|
-
module ActiveJob
|
2
|
-
module Locking
|
3
|
-
module Unique
|
4
|
-
extend ::ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
include ::ActiveJob::Locking::Base
|
8
|
-
|
9
|
-
before_enqueue do |job|
|
10
|
-
lock = job.adapter.lock
|
11
|
-
throw :abort unless lock
|
12
|
-
end
|
13
|
-
|
14
|
-
rescue_from(Exception) do |exception|
|
15
|
-
self.adapter.unlock
|
16
|
-
raise
|
17
|
-
end
|
18
|
-
|
19
|
-
after_perform do |job|
|
20
|
-
job.adapter.unlock
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
1
|
+
module ActiveJob
|
2
|
+
module Locking
|
3
|
+
module Unique
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include ::ActiveJob::Locking::Base
|
8
|
+
|
9
|
+
before_enqueue do |job|
|
10
|
+
lock = job.adapter.lock
|
11
|
+
throw :abort unless lock
|
12
|
+
end
|
13
|
+
|
14
|
+
rescue_from(Exception) do |exception|
|
15
|
+
self.adapter.unlock
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
|
19
|
+
after_perform do |job|
|
20
|
+
job.adapter.unlock
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/test/serialized_tests.rb
CHANGED
@@ -1,63 +1,63 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
module SerializedTests
|
4
|
-
def test_one_completed
|
5
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
6
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
7
|
-
|
8
|
-
start_time = Time.now
|
9
|
-
sleep_time = SerialJob.lock_acquire_time / 0.9
|
10
|
-
threads = 3.times.map do |i|
|
11
|
-
Thread.new do
|
12
|
-
SerialJob.perform_later(i, sleep_time)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
17
|
-
threads.each {|thread| thread.join}
|
18
|
-
assert_equal(2, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
19
|
-
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
20
|
-
|
21
|
-
assert(Time.now - start_time > (1 * sleep_time))
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_some_completed
|
25
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
26
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
27
|
-
|
28
|
-
start_time = Time.now
|
29
|
-
sleep_time = SerialJob.lock_acquire_time / 1.9
|
30
|
-
threads = 3.times.map do |i|
|
31
|
-
Thread.new do
|
32
|
-
SerialJob.perform_later(i, sleep_time)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
37
|
-
threads.each {|thread| thread.join}
|
38
|
-
assert_equal(1, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
39
|
-
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
40
|
-
|
41
|
-
assert(Time.now - start_time > (1 * sleep_time))
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_all_completed
|
45
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
46
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
47
|
-
|
48
|
-
start_time = Time.now
|
49
|
-
sleep_time = SerialJob.lock_acquire_time / 4
|
50
|
-
threads = 3.times.map do |i|
|
51
|
-
Thread.new do
|
52
|
-
SerialJob.perform_later(i, sleep_time)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
57
|
-
threads.each {|thread| thread.join}
|
58
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
59
|
-
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
60
|
-
|
61
|
-
assert(Time.now - start_time > (1 * sleep_time))
|
62
|
-
end
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module SerializedTests
|
4
|
+
def test_one_completed
|
5
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
6
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
7
|
+
|
8
|
+
start_time = Time.now
|
9
|
+
sleep_time = SerialJob.lock_acquire_time / 0.9
|
10
|
+
threads = 3.times.map do |i|
|
11
|
+
Thread.new do
|
12
|
+
SerialJob.perform_later(i, sleep_time)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
17
|
+
threads.each {|thread| thread.join}
|
18
|
+
assert_equal(2, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
19
|
+
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
20
|
+
|
21
|
+
assert(Time.now - start_time > (1 * sleep_time))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_some_completed
|
25
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
26
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
27
|
+
|
28
|
+
start_time = Time.now
|
29
|
+
sleep_time = SerialJob.lock_acquire_time / 1.9
|
30
|
+
threads = 3.times.map do |i|
|
31
|
+
Thread.new do
|
32
|
+
SerialJob.perform_later(i, sleep_time)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
37
|
+
threads.each {|thread| thread.join}
|
38
|
+
assert_equal(1, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
39
|
+
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
40
|
+
|
41
|
+
assert(Time.now - start_time > (1 * sleep_time))
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_all_completed
|
45
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
46
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
47
|
+
|
48
|
+
start_time = Time.now
|
49
|
+
sleep_time = SerialJob.lock_acquire_time / 4
|
50
|
+
threads = 3.times.map do |i|
|
51
|
+
Thread.new do
|
52
|
+
SerialJob.perform_later(i, sleep_time)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# All the threads will complete after the sleep time has expired - since two jobs get requeued
|
57
|
+
threads.each {|thread| thread.join}
|
58
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
59
|
+
assert_equal(3, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
60
|
+
|
61
|
+
assert(Time.now - start_time > (1 * sleep_time))
|
62
|
+
end
|
63
63
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler.require(:default, :test)
|
3
|
-
|
4
|
-
require 'minitest/autorun'
|
5
|
-
|
6
|
-
# To make debugging easier, test within this source tree versus an installed gem
|
7
|
-
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
8
|
-
require 'activejob-locking'
|
9
|
-
|
10
|
-
require 'activejob/locking/adapters/redis-semaphore'
|
11
|
-
require 'activejob/locking/adapters/redlock'
|
12
|
-
require 'activejob/locking/adapters/suo-redis'
|
13
|
-
|
14
|
-
require_relative './jobs/unique_job'
|
15
|
-
require_relative './jobs/fail_job'
|
16
|
-
require_relative './jobs/serial_job'
|
17
|
-
|
18
|
-
def redis_reset
|
19
|
-
Kernel.system('redis-cli FLUSHALL')
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require(:default, :test)
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
# To make debugging easier, test within this source tree versus an installed gem
|
7
|
+
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
|
8
|
+
require 'activejob-locking'
|
9
|
+
|
10
|
+
require 'activejob/locking/adapters/redis-semaphore'
|
11
|
+
require 'activejob/locking/adapters/redlock'
|
12
|
+
require 'activejob/locking/adapters/suo-redis'
|
13
|
+
|
14
|
+
require_relative './jobs/unique_job'
|
15
|
+
require_relative './jobs/fail_job'
|
16
|
+
require_relative './jobs/serial_job'
|
17
|
+
|
18
|
+
def redis_reset
|
19
|
+
Kernel.system('redis-cli FLUSHALL')
|
20
20
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require_relative('./serialized_tests')
|
2
|
-
|
3
|
-
class SerializedMemory < MiniTest::Test
|
4
|
-
include SerializedTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
ActiveJob::Base.queue_adapter = :test
|
8
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
9
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Memory
|
10
|
-
end
|
1
|
+
require_relative('./serialized_tests')
|
2
|
+
|
3
|
+
class SerializedMemory < MiniTest::Test
|
4
|
+
include SerializedTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
ActiveJob::Base.queue_adapter = :test
|
8
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
9
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Memory
|
10
|
+
end
|
11
11
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative('./serialized_tests')
|
2
|
-
|
3
|
-
class UniqueRedisSemaphoreTest < MiniTest::Test
|
4
|
-
include SerializedTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
ActiveJob::Base.queue_adapter = :test
|
9
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::RedisSemaphore
|
11
|
-
end
|
1
|
+
require_relative('./serialized_tests')
|
2
|
+
|
3
|
+
class UniqueRedisSemaphoreTest < MiniTest::Test
|
4
|
+
include SerializedTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
ActiveJob::Base.queue_adapter = :test
|
9
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::RedisSemaphore
|
11
|
+
end
|
12
12
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require_relative('./serialized_tests')
|
2
|
-
|
3
|
-
class SerializedRedlockTest < MiniTest::Test
|
4
|
-
include SerializedTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
|
9
|
-
ActiveJob::Base.queue_adapter = :test
|
10
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
11
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Redlock
|
12
|
-
ActiveJob::Locking.options.hosts = Redlock::Client::DEFAULT_REDIS_URLS
|
13
|
-
end
|
1
|
+
require_relative('./serialized_tests')
|
2
|
+
|
3
|
+
class SerializedRedlockTest < MiniTest::Test
|
4
|
+
include SerializedTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
|
9
|
+
ActiveJob::Base.queue_adapter = :test
|
10
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
11
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Redlock
|
12
|
+
ActiveJob::Locking.options.hosts = Redlock::Client::DEFAULT_REDIS_URLS
|
13
|
+
end
|
14
14
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative('./serialized_tests')
|
2
|
-
|
3
|
-
class SerializedSuoRedisTest < MiniTest::Test
|
4
|
-
include SerializedTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
ActiveJob::Base.queue_adapter = :test
|
9
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
|
11
|
-
end
|
1
|
+
require_relative('./serialized_tests')
|
2
|
+
|
3
|
+
class SerializedSuoRedisTest < MiniTest::Test
|
4
|
+
include SerializedTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
ActiveJob::Base.queue_adapter = :test
|
9
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
|
11
|
+
end
|
12
12
|
end
|
data/test/test_unique_memory.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative('./unique_tests')
|
2
|
-
|
3
|
-
class UniqueMemoryTest < MiniTest::Test
|
4
|
-
include UniqueTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
ActiveJob::Locking::Adapters::Memory.reset
|
8
|
-
ActiveJob::Base.queue_adapter = :test
|
9
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Memory
|
11
|
-
end
|
12
|
-
end
|
1
|
+
require_relative('./unique_tests')
|
2
|
+
|
3
|
+
class UniqueMemoryTest < MiniTest::Test
|
4
|
+
include UniqueTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
ActiveJob::Locking::Adapters::Memory.reset
|
8
|
+
ActiveJob::Base.queue_adapter = :test
|
9
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Memory
|
11
|
+
end
|
12
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative('./unique_tests')
|
2
|
-
|
3
|
-
class UniqueRedisSemaphoreTest < MiniTest::Test
|
4
|
-
include UniqueTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
ActiveJob::Base.queue_adapter = :test
|
9
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::RedisSemaphore
|
11
|
-
end
|
1
|
+
require_relative('./unique_tests')
|
2
|
+
|
3
|
+
class UniqueRedisSemaphoreTest < MiniTest::Test
|
4
|
+
include UniqueTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
ActiveJob::Base.queue_adapter = :test
|
9
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::RedisSemaphore
|
11
|
+
end
|
12
12
|
end
|
data/test/test_unique_redlock.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require_relative('./unique_tests')
|
2
|
-
|
3
|
-
class UniqueRedlockTest < MiniTest::Test
|
4
|
-
include UniqueTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
|
9
|
-
ActiveJob::Base.queue_adapter = :test
|
10
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
11
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Redlock
|
12
|
-
ActiveJob::Locking.options.hosts = Redlock::Client::DEFAULT_REDIS_URLS
|
13
|
-
end
|
1
|
+
require_relative('./unique_tests')
|
2
|
+
|
3
|
+
class UniqueRedlockTest < MiniTest::Test
|
4
|
+
include UniqueTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
|
9
|
+
ActiveJob::Base.queue_adapter = :test
|
10
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
11
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::Redlock
|
12
|
+
ActiveJob::Locking.options.hosts = Redlock::Client::DEFAULT_REDIS_URLS
|
13
|
+
end
|
14
14
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative('./unique_tests')
|
2
|
-
|
3
|
-
class UniqueSuoRedisTest < MiniTest::Test
|
4
|
-
include UniqueTests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
redis_reset
|
8
|
-
ActiveJob::Base.queue_adapter = :test
|
9
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
-
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
|
11
|
-
end
|
1
|
+
require_relative('./unique_tests')
|
2
|
+
|
3
|
+
class UniqueSuoRedisTest < MiniTest::Test
|
4
|
+
include UniqueTests
|
5
|
+
|
6
|
+
def setup
|
7
|
+
redis_reset
|
8
|
+
ActiveJob::Base.queue_adapter = :test
|
9
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
10
|
+
ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
|
11
|
+
end
|
12
12
|
end
|
data/test/unique_tests.rb
CHANGED
@@ -1,100 +1,100 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
module UniqueTests
|
4
|
-
def test_none_performed
|
5
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = false
|
6
|
-
|
7
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
8
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
9
|
-
|
10
|
-
sleep_time = UniqueJob.lock_acquire_time
|
11
|
-
threads = 3.times.map do |i|
|
12
|
-
Thread.new do
|
13
|
-
UniqueJob.perform_later(i, sleep_time)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
threads.each {|thread| thread.join}
|
18
|
-
assert_equal(1, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
19
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
20
|
-
ensure
|
21
|
-
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
22
|
-
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_one_performed
|
26
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
27
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
28
|
-
|
29
|
-
sleep_time = UniqueJob.lock_acquire_time * 2
|
30
|
-
threads = 3.times.map do |i|
|
31
|
-
Thread.new do
|
32
|
-
UniqueJob.perform_later(i, sleep_time)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
threads.each {|thread| thread.join}
|
37
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
38
|
-
assert_equal(1, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_all_performed
|
42
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
43
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
44
|
-
|
45
|
-
start_time = Time.now
|
46
|
-
sleep_time = UniqueJob.lock_acquire_time / 4.0
|
47
|
-
threads = 3.times.map do |i|
|
48
|
-
Thread.new do
|
49
|
-
UniqueJob.perform_later(i, sleep_time)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
threads.each {|thread| thread.join}
|
54
|
-
|
55
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
56
|
-
assert_equal(threads.count, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
57
|
-
assert(Time.now - start_time > (threads.count * sleep_time))
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_some_performed
|
61
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
62
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
63
|
-
|
64
|
-
start_time = Time.now
|
65
|
-
sleep_time = UniqueJob.lock_acquire_time / 2.0
|
66
|
-
threads = 3.times.map do |i|
|
67
|
-
Thread.new do
|
68
|
-
UniqueJob.perform_later(i, sleep_time)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
threads.each {|thread| thread.join}
|
73
|
-
|
74
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
75
|
-
assert_equal(threads.count - 1, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
76
|
-
assert(Time.now - start_time > ((threads.count - 1) * sleep_time))
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_fail
|
80
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
81
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
82
|
-
|
83
|
-
start_time = Time.now
|
84
|
-
sleep_time = UniqueJob.lock_acquire_time
|
85
|
-
threads = 3.times.map do |i|
|
86
|
-
Thread.new do
|
87
|
-
begin
|
88
|
-
FailJob.perform_later(i, sleep_time)
|
89
|
-
rescue => e
|
90
|
-
# do nothing
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
threads.each {|thread| thread.join}
|
96
|
-
|
97
|
-
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
98
|
-
assert_equal(threads.count, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
99
|
-
end
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
module UniqueTests
|
4
|
+
def test_none_performed
|
5
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = false
|
6
|
+
|
7
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
8
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
9
|
+
|
10
|
+
sleep_time = UniqueJob.lock_acquire_time
|
11
|
+
threads = 3.times.map do |i|
|
12
|
+
Thread.new do
|
13
|
+
UniqueJob.perform_later(i, sleep_time)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
threads.each {|thread| thread.join}
|
18
|
+
assert_equal(1, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
19
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
20
|
+
ensure
|
21
|
+
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
|
22
|
+
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_one_performed
|
26
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
27
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
28
|
+
|
29
|
+
sleep_time = UniqueJob.lock_acquire_time * 2
|
30
|
+
threads = 3.times.map do |i|
|
31
|
+
Thread.new do
|
32
|
+
UniqueJob.perform_later(i, sleep_time)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
threads.each {|thread| thread.join}
|
37
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
38
|
+
assert_equal(1, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_all_performed
|
42
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
43
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
44
|
+
|
45
|
+
start_time = Time.now
|
46
|
+
sleep_time = UniqueJob.lock_acquire_time / 4.0
|
47
|
+
threads = 3.times.map do |i|
|
48
|
+
Thread.new do
|
49
|
+
UniqueJob.perform_later(i, sleep_time)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
threads.each {|thread| thread.join}
|
54
|
+
|
55
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
56
|
+
assert_equal(threads.count, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
57
|
+
assert(Time.now - start_time > (threads.count * sleep_time))
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_some_performed
|
61
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
62
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
63
|
+
|
64
|
+
start_time = Time.now
|
65
|
+
sleep_time = UniqueJob.lock_acquire_time / 2.0
|
66
|
+
threads = 3.times.map do |i|
|
67
|
+
Thread.new do
|
68
|
+
UniqueJob.perform_later(i, sleep_time)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
threads.each {|thread| thread.join}
|
73
|
+
|
74
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
75
|
+
assert_equal(threads.count - 1, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
76
|
+
assert(Time.now - start_time > ((threads.count - 1) * sleep_time))
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_fail
|
80
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
81
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
82
|
+
|
83
|
+
start_time = Time.now
|
84
|
+
sleep_time = UniqueJob.lock_acquire_time
|
85
|
+
threads = 3.times.map do |i|
|
86
|
+
Thread.new do
|
87
|
+
begin
|
88
|
+
FailJob.perform_later(i, sleep_time)
|
89
|
+
rescue => e
|
90
|
+
# do nothing
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
threads.each {|thread| thread.join}
|
96
|
+
|
97
|
+
assert_equal(0, ActiveJob::Base.queue_adapter.enqueued_jobs.count)
|
98
|
+
assert_equal(threads.count, ActiveJob::Base.queue_adapter.performed_jobs.count)
|
99
|
+
end
|
100
100
|
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activejob-locking
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Savage
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-05-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: redis-mutex
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,8 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '0'
|
155
155
|
requirements: []
|
156
|
-
|
157
|
-
rubygems_version: 2.6.13
|
156
|
+
rubygems_version: 3.0.3
|
158
157
|
signing_key:
|
159
158
|
specification_version: 4
|
160
159
|
summary: ActiveJob locking to control how jobs are enqueued and performed.
|