activejob-locking 0.4.0 → 0.6.2

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.
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,23 +1,24 @@
1
- require 'activejob/locking/adapters/base'
2
- require 'activejob/locking/adapters/memory'
3
-
4
- require 'activejob/locking/base'
5
- require 'activejob/locking/unique'
6
- require 'activejob/locking/serialized'
7
-
8
- require 'activejob/locking/options'
9
-
10
- module ActiveJob
11
- module Locking
12
- @options = ActiveJob::Locking::Options.new(adapter: ActiveJob::Locking::Adapters::Memory,
13
- hosts: ['localhost'],
14
- lock_time: 100,
15
- lock_acquire_time: 1,
16
- adapter_options: {})
17
-
18
- def self.options
19
- @options
20
- end
21
- end
22
- end
23
-
1
+ require 'activejob/locking/adapters/base'
2
+ require 'activejob/locking/adapters/memory'
3
+
4
+ require 'activejob/locking/base'
5
+ require 'activejob/locking/unique'
6
+ require 'activejob/locking/serialized'
7
+
8
+ require 'activejob/locking/options'
9
+
10
+ module ActiveJob
11
+ module Locking
12
+ @options = ActiveJob::Locking::Options.new(adapter: ActiveJob::Locking::Adapters::Memory,
13
+ hosts: ['localhost'],
14
+ enqueue_time: 100, # seconds
15
+ lock_time: 100, # seconds
16
+ lock_acquire_time: 1, # seconds
17
+ adapter_options: {})
18
+
19
+ def self.options
20
+ @options
21
+ end
22
+ end
23
+ end
24
+
@@ -1,32 +1,32 @@
1
- module ActiveJob
2
- module Locking
3
- module Adapters
4
- class Base
5
- attr_reader :key, :options, :lock_manager
6
- attr_accessor :lock_token
7
-
8
- def initialize(key, options)
9
- @key = key
10
- @options = options
11
- @lock_manager = self.create_lock_manager
12
- end
13
-
14
- def create_lock_manager
15
- raise('Subclass must implement')
16
- end
17
-
18
- def lock
19
- raise('Subclass must implement')
20
- end
21
-
22
- def unlock
23
- raise('Subclass must implement')
24
- end
25
-
26
- def refresh_lock!(refresh)
27
- raise('Subclass must implement')
28
- end
29
- end
30
- end
31
- end
1
+ module ActiveJob
2
+ module Locking
3
+ module Adapters
4
+ class Base
5
+ attr_reader :key, :options, :lock_manager
6
+ attr_accessor :lock_token
7
+
8
+ def initialize(key, options)
9
+ @key = key
10
+ @options = options
11
+ @lock_manager = self.create_lock_manager
12
+ end
13
+
14
+ def create_lock_manager
15
+ raise('Subclass must implement')
16
+ end
17
+
18
+ def lock
19
+ raise('Subclass must implement')
20
+ end
21
+
22
+ def unlock
23
+ raise('Subclass must implement')
24
+ end
25
+
26
+ def refresh_lock!(refresh)
27
+ raise('Subclass must implement')
28
+ end
29
+ end
30
+ end
31
+ end
32
32
  end
@@ -1,58 +1,58 @@
1
- module ActiveJob
2
- module Locking
3
- module Adapters
4
- class Memory < Base
5
- @hash = Hash.new
6
- @mutex = Mutex.new
7
-
8
- def self.lock(key)
9
- @mutex.synchronize do
10
- if @hash[key]
11
- false
12
- else
13
- @hash[key] = Time.now
14
- end
15
- end
16
- end
17
-
18
- def self.unlock(key)
19
- @mutex.synchronize do
20
- @hash.delete(key)
21
- end
22
- end
23
-
24
- def self.locked?(key)
25
- @mutex.synchronize do
26
- @hash.include?(key)
27
- end
28
- end
29
-
30
- def self.reset
31
- @mutex.synchronize do
32
- @hash = Hash.new
33
- end
34
- end
35
-
36
- def create_lock_manager
37
- end
38
-
39
- def lock
40
- finish = Time.now + self.options.lock_acquire_time
41
- sleep_time = [5, self.options.lock_acquire_time / 5].min
42
-
43
- begin
44
- lock = self.class.lock(key)
45
- return lock if lock
46
- sleep(sleep_time)
47
- end while Time.now < finish
48
-
49
- false
50
- end
51
-
52
- def unlock
53
- self.class.unlock(self.key)
54
- end
55
- end
56
- end
57
- end
1
+ module ActiveJob
2
+ module Locking
3
+ module Adapters
4
+ class Memory < Base
5
+ @hash = Hash.new
6
+ @mutex = Mutex.new
7
+
8
+ def self.lock(key)
9
+ @mutex.synchronize do
10
+ if @hash[key]
11
+ false
12
+ else
13
+ @hash[key] = Time.now
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.unlock(key)
19
+ @mutex.synchronize do
20
+ @hash.delete(key)
21
+ end
22
+ end
23
+
24
+ def self.locked?(key)
25
+ @mutex.synchronize do
26
+ @hash.include?(key)
27
+ end
28
+ end
29
+
30
+ def self.reset
31
+ @mutex.synchronize do
32
+ @hash = Hash.new
33
+ end
34
+ end
35
+
36
+ def create_lock_manager
37
+ end
38
+
39
+ def lock
40
+ finish = Time.now + self.options.lock_acquire_time
41
+ sleep_time = [5, self.options.lock_acquire_time / 5].min
42
+
43
+ begin
44
+ lock = self.class.lock(key)
45
+ return lock if lock
46
+ sleep(sleep_time)
47
+ end while Time.now < finish
48
+
49
+ false
50
+ end
51
+
52
+ def unlock
53
+ self.class.unlock(self.key)
54
+ end
55
+ end
56
+ end
57
+ end
58
58
  end
@@ -1,26 +1,26 @@
1
- require 'redis-semaphore'
2
-
3
- module ActiveJob
4
- module Locking
5
- module Adapters
6
- class RedisSemaphore < Base
7
- def create_lock_manager
8
- mapped_options = {host: self.options.hosts.first,
9
- resources: 1,
10
- stale_client_timeout: self.options.lock_time}.merge(self.options.adapter_options)
11
-
12
- Redis::Semaphore.new(self.key, mapped_options)
13
- end
14
-
15
- def lock
16
- self.lock_token = self.lock_manager.lock(self.options.lock_acquire_time)
17
- end
18
-
19
- def unlock
20
- self.lock_manager.signal(self.lock_token)
21
- self.lock_token = nil
22
- end
23
- end
24
- end
25
- end
26
- end
1
+ require 'redis-semaphore'
2
+
3
+ module ActiveJob
4
+ module Locking
5
+ module Adapters
6
+ class RedisSemaphore < Base
7
+ def create_lock_manager
8
+ mapped_options = {host: self.options.hosts.first,
9
+ resources: 1,
10
+ stale_client_timeout: self.options.lock_time}.merge(self.options.adapter_options)
11
+
12
+ Redis::Semaphore.new(self.key, mapped_options)
13
+ end
14
+
15
+ def lock
16
+ self.lock_token = self.lock_manager.lock(self.options.lock_acquire_time)
17
+ end
18
+
19
+ def unlock
20
+ self.lock_manager.signal(self.lock_token)
21
+ self.lock_token = nil
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,26 +1,26 @@
1
- require 'redlock'
2
-
3
- module ActiveJob
4
- module Locking
5
- module Adapters
6
- class Redlock < Base
7
- def create_lock_manager
8
- mapped_options = self.options.adapter_options
9
- mapped_options[:retry_count] = 2 # Try to get the lock and then try again when timeout is expiring--
10
- mapped_options[:retry_delay] = self.options.lock_acquire_time * 1000 # convert from seconds to milliseconds
11
-
12
- ::Redlock::Client.new(self.options.hosts, mapped_options)
13
- end
14
-
15
- def lock
16
- self.lock_token = self.lock_manager.lock(self.key, self.options.lock_time * 1000)
17
- end
18
-
19
- def unlock
20
- self.lock_manager.unlock(self.lock_token)
21
- self.lock_token = nil
22
- end
23
- end
24
- end
25
- end
26
- end
1
+ require 'redlock'
2
+
3
+ module ActiveJob
4
+ module Locking
5
+ module Adapters
6
+ class Redlock < Base
7
+ def create_lock_manager
8
+ mapped_options = self.options.adapter_options
9
+ mapped_options[:retry_count] = 2 # Try to get the lock and then try again when timeout is expiring--
10
+ mapped_options[:retry_delay] = self.options.lock_acquire_time * 1000 # convert from seconds to milliseconds
11
+
12
+ ::Redlock::Client.new(self.options.hosts, mapped_options)
13
+ end
14
+
15
+ def lock
16
+ self.lock_token = self.lock_manager.lock(self.key, self.options.lock_time * 1000)
17
+ end
18
+
19
+ def unlock
20
+ self.lock_manager.unlock(self.lock_token.symbolize_keys)
21
+ self.lock_token = nil
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,25 +1,25 @@
1
- require 'suo'
2
-
3
- module ActiveJob
4
- module Locking
5
- module Adapters
6
- class SuoRedis < Base
7
- def create_lock_manager
8
- mapped_options = {connection: {host: self.options.hosts.first},
9
- stale_lock_expiration: self.options.lock_time,
10
- acquisition_timeout: self.options.lock_acquire_time}
11
-
12
- Suo::Client::Redis.new(self.key, mapped_options)
13
- end
14
-
15
- def lock
16
- self.lock_token = self.lock_manager.lock
17
- end
18
-
19
- def unlock
20
- self.lock_manager.unlock(self.lock_token)
21
- end
22
- end
23
- end
24
- end
25
- end
1
+ require 'suo'
2
+
3
+ module ActiveJob
4
+ module Locking
5
+ module Adapters
6
+ class SuoRedis < Base
7
+ def create_lock_manager
8
+ mapped_options = {connection: {host: self.options.hosts.first},
9
+ stale_lock_expiration: self.options.lock_time,
10
+ acquisition_timeout: self.options.lock_acquire_time}
11
+
12
+ Suo::Client::Redis.new(self.key, mapped_options)
13
+ end
14
+
15
+ def lock
16
+ self.lock_token = self.lock_manager.lock
17
+ end
18
+
19
+ def unlock
20
+ self.lock_manager.unlock(self.lock_token)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,51 +1,55 @@
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, :hosts, :lock_time, :lock_acquire_time, :adapter_options, to: :lock_options
11
- delegate :adapter=, :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
+ begin
35
+ deserialize_arguments_if_needed
36
+ rescue => exception
37
+ rescue_with_handler(exception) || raise
38
+ end
39
+
40
+ # Merge local and global options
41
+ merged_options = ActiveJob::Locking.options.dup.merge(self.class.lock_options)
42
+
43
+ # Get the key
44
+ base_key = self.lock_key(*self.arguments)
45
+ key = "activejoblocking:#{base_key}"
46
+
47
+ # Remember the lock might be acquired in one process and released in another
48
+ merged_options.adapter.new(key, merged_options)
49
+ end
50
+ @adapter
51
+ end
52
+ end
53
+ end
54
+ end
51
55
  end