Class: GCSLock::Mutex
- Inherits:
-
Object
- Object
- GCSLock::Mutex
- Defined in:
- lib/gcslock/mutex.rb
Instance Method Summary collapse
-
#initialize(bucket, object, client: nil, uuid: nil, min_backoff: nil, max_backoff: nil) ⇒ Mutex
constructor
A new instance of Mutex.
-
#lock(timeout: nil) ⇒ Boolean
Attempts to grab the lock and waits if it isn’t available.
-
#locked? ⇒ Boolean
Verifies if the lock is already taken.
-
#owned? ⇒ Boolean
Verifies if the lock is already owned by this instance.
-
#synchronize(timeout: nil) ⇒ Object
Obtains a lock, runs the block, and releases the lock when the block completes.
-
#try_lock ⇒ Boolean
Attempts to obtain the lock and returns immediately.
-
#unlock ⇒ Object
Releases the lock.
-
#unlock! ⇒ Object
Releases the lock even if not owned by this instance.
Constructor Details
#initialize(bucket, object, client: nil, uuid: nil, min_backoff: nil, max_backoff: nil) ⇒ Mutex
Returns a new instance of Mutex.
9 10 11 12 13 14 15 16 17 |
# File 'lib/gcslock/mutex.rb', line 9 def initialize(bucket, object, client: nil, uuid: nil, min_backoff: nil, max_backoff: nil) @client = client || Google::Cloud::Storage.new @bucket = @client.bucket(bucket, skip_lookup: true) @object = @bucket.file(object, skip_lookup: true) @uuid = uuid || SecureRandom.uuid @min_backoff = min_backoff || 0.01 @max_backoff = max_backoff || 5.0 end |
Instance Method Details
#lock(timeout: nil) ⇒ Boolean
Attempts to grab the lock and waits if it isn’t available.
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/gcslock/mutex.rb', line 28 def lock(timeout: nil) raise LockAlreadyOwnedError, "Mutex for #{@object.name} is already owned by this process" if owned? begin Utils.backoff(min_backoff: @min_backoff, max_backoff: @max_backoff, timeout: timeout) do try_lock end rescue LockTimeoutError raise LockTimeoutError, "Unable to get mutex for #{@object.name} before timeout" end end |
#locked? ⇒ Boolean
Verifies if the lock is already taken.
43 44 45 46 47 48 |
# File 'lib/gcslock/mutex.rb', line 43 def locked? @object.reload! @object.exists? rescue Google::Cloud::NotFoundError false end |
#owned? ⇒ Boolean
Verifies if the lock is already owned by this instance.
53 54 55 |
# File 'lib/gcslock/mutex.rb', line 53 def owned? locked? && @object.size == @uuid.size && @object.download.read == @uuid end |
#synchronize(timeout: nil) ⇒ Object
Obtains a lock, runs the block, and releases the lock when the block completes.
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/gcslock/mutex.rb', line 66 def synchronize(timeout: nil) lock(timeout: timeout) begin block = yield ensure unlock end block end |
#try_lock ⇒ Boolean
Attempts to obtain the lock and returns immediately.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/gcslock/mutex.rb', line 80 def try_lock @client.service.service.insert_object( @bucket.name, name: @object.name, if_generation_match: 0, upload_source: StringIO.new(@uuid), ) true rescue Google::Apis::ClientError => e raise unless e.status_code == 412 && e..start_with?('conditionNotMet:') false end |
#unlock ⇒ Object
Releases the lock.
100 101 102 103 104 105 |
# File 'lib/gcslock/mutex.rb', line 100 def unlock raise LockNotOwnedError, "Mutex for #{@object.name} is not owned by this process" unless owned? @object.delete nil end |
#unlock! ⇒ Object
Releases the lock even if not owned by this instance.
112 113 114 115 116 117 118 |
# File 'lib/gcslock/mutex.rb', line 112 def unlock! @object.delete nil rescue Google::Cloud::NotFoundError => e raise LockNotFoundError, "Mutex for #{@object.name} not found" end |