with_process_lock 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0af2c6f49c7b058970c7fc98be0949625b6f005d
4
- data.tar.gz: '005991b9d6d6355c7c98e9ed0aa9241c3e2b147d'
3
+ metadata.gz: aa3c649e6d7f28c49dc515e0f1fc851921500bc0
4
+ data.tar.gz: b24366c20a4ee898d385af92aeda3cc26b5b8075
5
5
  SHA512:
6
- metadata.gz: 7c34ceac06e7d7e8ffdb256a968a9e8464161fc742065cc3679ab5acdc19c810099c30f084f59940a746d913285509db1bc679426101d0296bc4e3ad6bd05eda
7
- data.tar.gz: 6a700c32cff253497e62aa6e668b95b692ce359dbff3d5e5786154dd00687585ab2e89ea290a2df4164cf7bb23388c0adf73cda47693c3087117502ef25fa9c2
6
+ metadata.gz: e4e1a90d66242b191695f42f26ffd548c8a3d3ef46d7c753cfbddc622d4fda065758b83ff5dfbcc095095b9e1f2a902aa0291739de4aeb1a5c91cadf223754e5
7
+ data.tar.gz: b4bdd542ced26842e933f99ee754f0fc1b74ad95cabadf7200044d25367d0c39a5807047381566c04fd18039a0461afe4abab2d2c19aef264dcaaa1f971dcdd0
data/README.md CHANGED
@@ -29,13 +29,59 @@ Or install it yourself as:
29
29
 
30
30
  ## Usage
31
31
 
32
+ You can attempt to run a process once with `execute_once`. It will execute the
33
+ block if the process is not locked, otherwise it will raise an exception.
34
+
35
+ ```
36
+ ProcessLock::WithProcessLock.execute_once('unique_key_for_your_process') do
37
+ # The code to run in the process
38
+ do_stuff
39
+ end
40
+ ```
41
+
42
+ You can run a process with a retry:
43
+
44
+ ```
45
+ ProcessLock::WithProcessLock.execute_with_retry(
46
+ 'unique_key_for_your_process'
47
+ ) do
48
+ # The code to run in the process
49
+ do_stuff
50
+ end
32
51
  ```
33
- ProcessLock::WithProcessLock.execute('unique_key_for_your_process') do
52
+
53
+ This will retry running the block every 1 second until the process is unblocked.
54
+ The current thread will be blocked until the block successfully executes.
55
+ You can override the default retry wait by providing the `retry_wait` parameter
56
+ in seconds.
57
+
58
+ ```
59
+ ProcessLock::WithProcessLock.execute_with_retry(
60
+ 'unique_key_for_your_process',
61
+ retry_wait: 2
62
+ ) do
63
+ # The code to run in the process
64
+ do_stuff
65
+ end
66
+ ```
67
+
68
+ If you don't want the retry to run forever, you can specify a timeout by
69
+ providing the `timeout` parameter in seconds:
70
+
71
+
72
+ ```
73
+ ProcessLock::WithProcessLock.execute_with_retry(
74
+ 'unique_key_for_your_process',
75
+ retry_wait: 2,
76
+ timeout: 10
77
+ ) do
34
78
  # The code to run in the process
35
79
  do_stuff
36
80
  end
37
81
  ```
38
82
 
83
+ This will retry until the timeout time is expired, then raise an error.
84
+
39
85
  ## Development
40
86
 
41
87
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/process_lock.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'redis'
2
2
  require "process_lock/version"
3
+ require "process_lock/execute_once"
4
+ require "process_lock/execute_with_retry"
3
5
  require "process_lock/with_process_lock"
6
+ require "process_lock/process_lock_error"
4
7
  module ProcessLock
5
8
 
6
9
  end
@@ -0,0 +1,15 @@
1
+ module ProcessLock
2
+ module ExecuteOnce
3
+ # Tries to run the given block and raises an exception if the process is
4
+ # locked
5
+ # @param key [String] The unique key to determine if the process is locked
6
+ def execute_once(key, &blk)
7
+ if can_execute?(key)
8
+ execute(key, &blk)
9
+ else
10
+ redis.quit
11
+ raise ProcessLockError, key: key
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,37 @@
1
+ module ProcessLock
2
+ module ExecuteWithRetry
3
+ # Tries to run the given block and retries every retry_wait seconds until
4
+ # the process in unblocked
5
+ # @param key [String] The unique key to determine if the process is locked
6
+ # @param retry_wait [Number] The number of seconds to wait in between
7
+ # retry attempts, defaulting to 1
8
+ # @param timeout [Number] The number of seconds until an exception should
9
+ # be raised instead of retrying, defaulting to nil (no timeout)
10
+ def execute_with_retry(
11
+ key,
12
+ retry_wait: 1,
13
+ timeout: nil,
14
+ &blk
15
+ )
16
+ if can_execute?(key)
17
+ execute(key, &blk)
18
+ else
19
+ # If there is time left before timeout or there is no timeout,
20
+ # wait retry_wait seconds and then recurse
21
+ if timeout.nil? || timeout >= retry_wait
22
+ sleep(retry_wait)
23
+ execute_with_retry(
24
+ key,
25
+ retry_wait: retry_wait,
26
+ timeout: timeout.nil? ? nil : timeout - retry_wait,
27
+ &blk
28
+ )
29
+ else
30
+ # If the timeout was reached, give up
31
+ redis.quit
32
+ raise ProcessLockError, key: key
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ module ProcessLock
2
+ class ProcessLockError < StandardError
3
+ def initialize(key:)
4
+ super("Can not run process because #{key} taken.")
5
+ end
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module ProcessLock
2
- VERSION = "0.1.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,28 +1,27 @@
1
1
  module ProcessLock
2
2
  class WithProcessLock
3
+ class << self
4
+ include ExecuteOnce
5
+ include ExecuteWithRetry
3
6
 
4
- def self.execute(key, &blk)
5
- if can_execute?(key)
7
+ private
8
+
9
+ def execute(key, &blk)
6
10
  redis.set(key, true)
7
- begin
8
- yield blk
9
- ensure
10
- # Delete the key and quit redis even if the block raises an exception
11
- redis.del(key)
12
- redis.quit
13
- end
14
- else
11
+ yield blk
12
+ ensure
13
+ # Delete the key and quit redis even if the block raises an exception
14
+ redis.del(key)
15
15
  redis.quit
16
- raise StandardError, "Can not run process because #{key} taken."
17
16
  end
18
- end
19
17
 
20
- def self.can_execute?(key)
21
- !redis.exists(key)
22
- end
18
+ def can_execute?(key)
19
+ !redis.exists(key)
20
+ end
23
21
 
24
- def self.redis
25
- @_redis ||= Redis.new
22
+ def redis
23
+ @_redis ||= Redis.new
24
+ end
26
25
  end
27
26
  end
28
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: with_process_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Friedman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2017-05-01 00:00:00.000000000 Z
13
+ date: 2017-05-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: redis
@@ -141,6 +141,9 @@ files:
141
141
  - bin/console
142
142
  - bin/setup
143
143
  - lib/process_lock.rb
144
+ - lib/process_lock/execute_once.rb
145
+ - lib/process_lock/execute_with_retry.rb
146
+ - lib/process_lock/process_lock_error.rb
144
147
  - lib/process_lock/version.rb
145
148
  - lib/process_lock/with_process_lock.rb
146
149
  - process_lock.gemspec