philiprehberger-lock_kit 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f82a00dac3cb9f7457b0d6e98d97a14a86502b1d2b2fe688b5bef0c07dcdbda1
4
- data.tar.gz: 88e1f0ac7f71c7585e7730b3984a9d4646c63ec7324f23731d2c088806257a3a
3
+ metadata.gz: ea17573729655a3a771771a4491e4ad67313ccdd8c1910964efc84e28cc55cd1
4
+ data.tar.gz: 3d045b798cd8f8b4df88af8127d4fb1ecd30c0ba252a1058fc90095fc4b98b75
5
5
  SHA512:
6
- metadata.gz: ba54abec814f3c18e17f0942f6954b3d108f59ea302ab8ae82efa21afaf118d911b9cc1c6ad1b089ad15b89faacb1c586372cf0b85ac5fe9a2843c4d89ce5f19
7
- data.tar.gz: 45248d0994c40fb782df7ce7185992c7a440267ad7fbc5bd43a27d2b0dc18b10172885b4b4c86aa9ddad550993a1ca661a43f979b7338d289fa0feffe128c5a9
6
+ metadata.gz: '08161efb6474fd3cc5b04d6896200df0e6c3e638e7eb89e898e2de4e0efee4ab2ac7decf99eea5f472a78c2914bbb1d5e4665e4d80a4fd7d72efdb3d4c942505'
7
+ data.tar.gz: 1776595c803f9c9285afc8bb6b7fc9f26cf32db45f1067a5f6084d585f741b5c27d6bce6ab2d1824c2db4941991e44bd1c0ac53e71f845e4011ac079b4f5f4af
data/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-04-15
11
+
12
+ ### Added
13
+ - `with_retry_lock(path, retries: 3, delay: 0.1, backoff: 2, timeout: nil, auto_cleanup: true, ttl: nil)` module method for lock acquisition with exponential backoff retries
14
+
10
15
  ## [0.3.0] - 2026-04-10
11
16
 
12
17
  ### Added
data/README.md CHANGED
@@ -64,6 +64,20 @@ Philiprehberger::LockKit.with_write_lock('/tmp/data.lock', timeout: 5) do
64
64
  end
65
65
  ```
66
66
 
67
+ ### Retry Lock
68
+
69
+ ```ruby
70
+ # Retries lock acquisition with exponential backoff
71
+ Philiprehberger::LockKit.with_retry_lock('/tmp/my.lock', retries: 5, delay: 0.2, backoff: 2) do
72
+ # acquired after retrying if initially contended
73
+ end
74
+
75
+ # With timeout per attempt, TTL, and custom cleanup
76
+ Philiprehberger::LockKit.with_retry_lock('/tmp/my.lock', retries: 3, delay: 0.1, backoff: 2, timeout: 5, ttl: 30) do
77
+ # each attempt waits up to 5s; lock expires after 30s
78
+ end
79
+ ```
80
+
67
81
  ### Lock with TTL (Time-to-Live)
68
82
 
69
83
  ```ruby
@@ -151,6 +165,7 @@ Philiprehberger::LockKit.stale?('/tmp/my_worker.pid') # => true/false
151
165
  | Method | Description |
152
166
  |--------|-------------|
153
167
  | `.with_file_lock(path, timeout: nil, auto_cleanup: false, on_wait: nil, ttl: nil) { }` | Execute block with exclusive file lock |
168
+ | `.with_retry_lock(path, retries: 3, delay: 0.1, backoff: 2, timeout: nil, auto_cleanup: true, ttl: nil) { }` | Execute block with file lock, retrying with exponential backoff |
154
169
  | `.with_pid_lock(name, dir: Dir.tmpdir, auto_cleanup: false, ttl: nil) { }` | Execute block with PID file lock |
155
170
  | `.with_read_lock(path, timeout: nil) { }` | Execute block with shared read lock |
156
171
  | `.with_write_lock(path, timeout: nil) { }` | Execute block with exclusive write lock |
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module LockKit
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -89,6 +89,35 @@ module Philiprehberger
89
89
  end
90
90
  end
91
91
 
92
+ # Execute a block with a file lock, retrying with exponential backoff on failure
93
+ #
94
+ # @param path [String] path to the lock file
95
+ # @param retries [Integer] maximum number of attempts
96
+ # @param delay [Numeric] initial delay in seconds between retries
97
+ # @param backoff [Numeric] multiplier applied to delay after each failed attempt
98
+ # @param timeout [Numeric, nil] seconds to wait per acquire attempt
99
+ # @param auto_cleanup [Boolean] automatically remove stale locks before acquiring
100
+ # @param ttl [Numeric, nil] time-to-live in seconds; lock expires after this duration
101
+ # @yield block to execute while the lock is held
102
+ # @return [Object] the return value of the block
103
+ # @raise [Error] if all retry attempts are exhausted
104
+ def self.with_retry_lock(path, retries: 3, delay: 0.1, backoff: 2, timeout: nil, auto_cleanup: true, ttl: nil, &block)
105
+ attempts = 0
106
+ current_delay = delay
107
+
108
+ loop do
109
+ attempts += 1
110
+ begin
111
+ return with_file_lock(path, timeout: timeout, auto_cleanup: auto_cleanup, ttl: ttl, &block)
112
+ rescue Error
113
+ raise if attempts >= retries
114
+
115
+ sleep current_delay
116
+ current_delay *= backoff
117
+ end
118
+ end
119
+ end
120
+
92
121
  # Check if a file is currently locked by another process
93
122
  #
94
123
  # @param path [String] path to the lock file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-lock_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-11 00:00:00.000000000 Z
11
+ date: 2026-04-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: File locks using flock and PID file locks with stale detection for coordinating
14
14
  between processes. Timeout support and automatic cleanup.