distributed-lock-google-cloud-storage 1.0.0 → 1.1.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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ba7bdb482b1bf1a10c8c3933ff8680d980099de2c66fd8cf0f1aac0db7c258d
|
4
|
+
data.tar.gz: 4597cc7ffd7ae791808eb677c875b62f19d48bcd8ff83c63a38a2f4683ec2829
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 323019ce82a1dda8252a9332dca0e024f5801ec5367320ad7e2133712cc55e35060f9fc2fb1bed1545dbfe333477b1498a2e410f4a77551d993ae7838e6f67eb
|
7
|
+
data.tar.gz: 2b7d1b8ff59ddfdd14d100fdd67420e57b54c2c87688ccfbbceff53c6b22561630e1f7c2a5803bb9329650f818134b514d5238264251af944024950a6260047c
|
@@ -11,6 +11,7 @@ require_relative 'utils'
|
|
11
11
|
module DistributedLock
|
12
12
|
module GoogleCloudStorage
|
13
13
|
class Lock
|
14
|
+
# @!visibility private
|
14
15
|
DEFAULT_INSTANCE_IDENTITY_PREFIX_WITHOUT_PID = SecureRandom.hex(12).freeze
|
15
16
|
|
16
17
|
include Utils
|
@@ -65,13 +66,13 @@ module DistributedLock
|
|
65
66
|
# when acquiring the lock fails. Must be at least 0.
|
66
67
|
# @param object_acl [String, nil] A predefined set of access control to apply to the Cloud Storage
|
67
68
|
# object. See the `acl` parameter in
|
68
|
-
# [https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Bucket.html#create_file-instance_method
|
69
|
+
# [Google::Cloud::Storage::Bucket#create_file](https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Bucket.html#create_file-instance_method)
|
69
70
|
# for acceptable values.
|
70
71
|
# @param cloud_storage_options [Hash, nil] Additional options to pass to
|
71
|
-
#
|
72
|
+
# [Google::Cloud::Storage.new](https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage.html#new-class_method).
|
72
73
|
# See its documentation to learn which options are available.
|
73
74
|
# @param cloud_storage_bucket_options [Hash, nil] Additional options to pass to
|
74
|
-
#
|
75
|
+
# [Google::Cloud::Storage::Project#bucket](https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Project.html#bucket-instance_method).
|
75
76
|
# See its documentation to learn which options are available.
|
76
77
|
#
|
77
78
|
# @note The logger must either be thread-safe, or all writes to this logger by anything besides
|
@@ -119,6 +120,7 @@ module DistributedLock
|
|
119
120
|
@owner = nil
|
120
121
|
@metageneration = nil
|
121
122
|
@refresher_thread = nil
|
123
|
+
@refresher_error = nil
|
122
124
|
|
123
125
|
# The refresher generation is incremented every time we shutdown
|
124
126
|
# the refresher thread. It allows the refresher thread to know
|
@@ -256,7 +258,7 @@ module DistributedLock
|
|
256
258
|
# obtained by some other instance identity, waits until it becomes available,
|
257
259
|
# or until timeout.
|
258
260
|
#
|
259
|
-
# Accepts the same parameters as #lock.
|
261
|
+
# Accepts the same parameters as {#lock}.
|
260
262
|
#
|
261
263
|
# @return The block's return value.
|
262
264
|
# @raise [AlreadyLockedError] This Lock instance — according to its internal state — believes
|
@@ -273,10 +275,10 @@ module DistributedLock
|
|
273
275
|
|
274
276
|
# Pretends like we've never obtained this lock, abandoning our internal state about the lock.
|
275
277
|
#
|
276
|
-
# Shuts down background lock refreshing, and ensures that
|
277
|
-
#
|
278
|
+
# Shuts down background lock refreshing, and ensures that {#locked_according_to_internal_state?}
|
279
|
+
# returns false.
|
278
280
|
#
|
279
|
-
# Does not modify any server data, so #locked_according_to_server? may still return true.
|
281
|
+
# Does not modify any server data, so {#locked_according_to_server?} may still return true.
|
280
282
|
#
|
281
283
|
# @return [void]
|
282
284
|
def abandon
|
@@ -302,15 +304,19 @@ module DistributedLock
|
|
302
304
|
# Returns whether the lock is healthy. A lock is considered healthy until
|
303
305
|
# we fail to refresh the lock too many times consecutively.
|
304
306
|
#
|
305
|
-
# Failure to refresh could happen for many reasons
|
306
|
-
#
|
307
|
+
# Failure to refresh could happen for many reasons. Some failures are temporary, such
|
308
|
+
# as network problems. Others are permanent, such as the lock object being forcefully
|
309
|
+
# deleted by someone else.
|
307
310
|
#
|
308
|
-
#
|
311
|
+
# Upon encountering a permanent failure, the lock is immediately declared unhealthy.
|
312
|
+
# Upon encountering a temporary failure, the lock is declared unhealthy after encountering
|
313
|
+
# a temporary error `max_refresh_fails` times consecutively.
|
309
314
|
#
|
310
315
|
# It only makes sense to call this method after having obtained this lock.
|
311
316
|
#
|
312
317
|
# @return [Boolean]
|
313
318
|
# @raise [NotLockedError] This lock was not obtained.
|
319
|
+
# @see #last_refresh_error
|
314
320
|
def healthy?
|
315
321
|
@state_mutex.synchronize do
|
316
322
|
raise NotLockedError, 'Not locked' if !unsynced_locked_according_to_internal_state?
|
@@ -318,7 +324,9 @@ module DistributedLock
|
|
318
324
|
end
|
319
325
|
end
|
320
326
|
|
321
|
-
# Checks whether the lock is healthy. See #healthy? for the definition of "healthy".
|
327
|
+
# Checks whether the lock is healthy. See {#healthy?} for the definition of "healthy".
|
328
|
+
# Use {#last_refresh_error} to query the last error that caused the lock to be declared
|
329
|
+
# unhealthy.
|
322
330
|
#
|
323
331
|
# It only makes sense to call this method after having obtained this lock.
|
324
332
|
#
|
@@ -329,6 +337,19 @@ module DistributedLock
|
|
329
337
|
raise LockUnhealthyError, 'Lock is not healthy' if !healthy?
|
330
338
|
end
|
331
339
|
|
340
|
+
# Returns the last error that caused the lock to be declared unhealthy.
|
341
|
+
#
|
342
|
+
# Don't use this method to check whether the lock is _currently_ healthy.
|
343
|
+
# If this lock has ever been unhealthy, then this method returns a non-nil value
|
344
|
+
# even if the lock is currently healthy.
|
345
|
+
#
|
346
|
+
# @return [StandardError, nil]
|
347
|
+
def last_refresh_error
|
348
|
+
@state_mutex.synchronize do
|
349
|
+
@refresher_error
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
332
353
|
|
333
354
|
private
|
334
355
|
|
@@ -429,9 +450,7 @@ module DistributedLock
|
|
429
450
|
def delete_lock_object(expected_metageneration)
|
430
451
|
file = @bucket.file(@path, skip_lookup: true)
|
431
452
|
file.delete(if_metageneration_match: expected_metageneration)
|
432
|
-
rescue Google::Cloud::NotFoundError
|
433
|
-
false
|
434
|
-
rescue Google::Cloud::FailedPreconditionError
|
453
|
+
rescue Google::Cloud::NotFoundError, Google::Cloud::FailedPreconditionError
|
435
454
|
false
|
436
455
|
end
|
437
456
|
|
@@ -563,7 +582,17 @@ module DistributedLock
|
|
563
582
|
end
|
564
583
|
log_debug { "Done refreshing lock. metageneration=#{file.metageneration}" }
|
565
584
|
true
|
585
|
+
|
566
586
|
rescue => e
|
587
|
+
@state_mutex.synchronize do
|
588
|
+
if @refresher_generation != refresher_generation
|
589
|
+
log_debug { 'Abort refreshing lock' }
|
590
|
+
return true
|
591
|
+
end
|
592
|
+
|
593
|
+
@refresher_error = e
|
594
|
+
end
|
595
|
+
|
567
596
|
log_error { "Error refreshing lock: #{e}" }
|
568
597
|
[false, permanent_failure]
|
569
598
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: distributed-lock-google-cloud-storage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hongli Lai
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-storage
|