philiprehberger-lock_kit 0.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea17573729655a3a771771a4491e4ad67313ccdd8c1910964efc84e28cc55cd1
4
- data.tar.gz: 3d045b798cd8f8b4df88af8127d4fb1ecd30c0ba252a1058fc90095fc4b98b75
3
+ metadata.gz: c73f047a2d1e5c9452f0c9ee35ea25f7129211c150c37e81ab8d64685a1e4335
4
+ data.tar.gz: 037df68b9cdbeffa96ed4a7a356bbed7df5ec0038f82421095c221c2f8937151
5
5
  SHA512:
6
- metadata.gz: '08161efb6474fd3cc5b04d6896200df0e6c3e638e7eb89e898e2de4e0efee4ab2ac7decf99eea5f472a78c2914bbb1d5e4665e4d80a4fd7d72efdb3d4c942505'
7
- data.tar.gz: 1776595c803f9c9285afc8bb6b7fc9f26cf32db45f1067a5f6084d585f741b5c27d6bce6ab2d1824c2db4941991e44bd1c0ac53e71f845e4011ac079b4f5f4af
6
+ metadata.gz: 86041b9199af015a6a6be088a589447d8bf53d60d47daf3f16d1ec4a98541c858fb85f6d3b09772fad2150793dd215b1f2955db62f7184d2bbbb9c76bf2b94a0
7
+ data.tar.gz: e6524a26607e7c72305bcb462d038fe2897c9511646ac9ba9dc29ac35d4e8954950f95c113dab0e18615d9d5be07a01f292b429ae509e5f6c6731adda6d43d8c
data/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] - 2026-05-07
11
+
12
+ ### Added
13
+ - `LockKit.age(path)` — returns the age in seconds of an active lock based on its `acquired_at` metadata, or `nil` if not locked or metadata is missing.
14
+
15
+ ## [0.5.0] - 2026-04-21
16
+
17
+ ### Added
18
+ - `ReadWriteLock#write_locked?` promoted to a public non-blocking query method
19
+ - `ReadWriteLock#stats` returning `{ readers:, write_locked: }` snapshot
20
+ - `LockKit.rw_stats(path)` module-level helper for the same snapshot without an instance
21
+
10
22
  ## [0.4.0] - 2026-04-15
11
23
 
12
24
  ### Added
data/README.md CHANGED
@@ -114,6 +114,14 @@ info = Philiprehberger::LockKit.owner('/tmp/my.lock')
114
114
  # => { pid: 12345, hostname: 'web-01', acquired_at: 2026-03-28 12:00:00 +0000 }
115
115
  ```
116
116
 
117
+ ### Lock Age
118
+
119
+ ```ruby
120
+ # Returns the age in seconds (Float) of an active lock, or nil if not locked
121
+ Philiprehberger::LockKit.age('/tmp/my.lock')
122
+ # => 12.34
123
+ ```
124
+
117
125
  ### Lock Waiting with Callbacks
118
126
 
119
127
  ```ruby
@@ -173,7 +181,9 @@ Philiprehberger::LockKit.stale?('/tmp/my_worker.pid') # => true/false
173
181
  | `.stale?(pid_file)` | Check if a PID file references a dead process |
174
182
  | `.expired?(path)` | Check if a lock has expired based on its TTL |
175
183
  | `.owner(path)` | Get lock owner metadata (pid, hostname, acquired_at) |
184
+ | `.age(path)` | Age in seconds of an active lock, or nil if not locked |
176
185
  | `.break!(path, force: false)` | Break a lock (stale only by default, any with force) |
186
+ | `.rw_stats(path)` | Snapshot of a read-write lock as `{ readers:, write_locked: }` |
177
187
 
178
188
  ### `LockKit::FileLock`
179
189
 
@@ -208,6 +218,8 @@ Philiprehberger::LockKit.stale?('/tmp/my_worker.pid') # => true/false
208
218
  | `#acquire_write(timeout: nil)` | Acquire exclusive write lock |
209
219
  | `#release_write` | Release the write lock |
210
220
  | `#reader_count` | Get current number of active readers |
221
+ | `#write_locked?` | Non-blocking check for an active write lock |
222
+ | `#stats` | Snapshot as `{ readers:, write_locked: }` |
211
223
 
212
224
  ## Development
213
225
 
@@ -126,8 +126,9 @@ module Philiprehberger
126
126
  0
127
127
  end
128
128
 
129
- private
130
-
129
+ # Non-blocking check for whether a write lock is currently held.
130
+ #
131
+ # @return [Boolean]
131
132
  def write_locked?
132
133
  return false unless File.exist?(@write_lock_path)
133
134
 
@@ -143,6 +144,13 @@ module Philiprehberger
143
144
  end
144
145
  end
145
146
 
147
+ # Snapshot of the current lock state: readers and writer presence.
148
+ #
149
+ # @return [Hash] `{ readers: Integer, write_locked: Boolean }`
150
+ def stats
151
+ { readers: reader_count, write_locked: write_locked? }
152
+ end
153
+
146
154
  def increment_readers
147
155
  update_reader_count(1)
148
156
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module LockKit
5
- VERSION = '0.4.0'
5
+ VERSION = '0.6.0'
6
6
  end
7
7
  end
@@ -126,6 +126,14 @@ module Philiprehberger
126
126
  FileLock.new(path).locked?
127
127
  end
128
128
 
129
+ # Snapshot of read-write lock state for `path` as `{ readers:, write_locked: }`.
130
+ #
131
+ # @param path [String] base path used with `with_read_lock` / `with_write_lock`
132
+ # @return [Hash] `{ readers: Integer, write_locked: Boolean }`
133
+ def self.rw_stats(path)
134
+ ReadWriteLock.new(path).stats
135
+ end
136
+
129
137
  # Check if a PID file references a dead process
130
138
  #
131
139
  # @param pid_file [String] path to the PID file
@@ -218,6 +226,17 @@ module Philiprehberger
218
226
  nil
219
227
  end
220
228
 
229
+ # Get the age in seconds of an active lock based on its `acquired_at` metadata
230
+ #
231
+ # @param path [String] path to the lock file or PID file
232
+ # @return [Float, nil] age in seconds, or nil if not locked or `acquired_at` is missing
233
+ def self.age(path)
234
+ data = owner(path)
235
+ return nil unless data && data[:acquired_at]
236
+
237
+ Time.now - data[:acquired_at]
238
+ end
239
+
221
240
  # Force break a lock
222
241
  #
223
242
  # @param path [String] path to the lock file or PID 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.4.0
4
+ version: 0.6.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-16 00:00:00.000000000 Z
11
+ date: 2026-05-07 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.