Class: DynamicLinks::Async::Locker

Inherits:
Object
  • Object
show all
Defined in:
lib/dynamic_links/async/locker.rb

Overview

Author:

Constant Summary collapse

LockAcquisitionError =
Class.new(StandardError)
LockReleaseError =
Class.new(StandardError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cache_store = DynamicLinks.configuration.cache_store) ⇒ Locker

Returns a new instance of Locker.



9
10
11
# File 'lib/dynamic_links/async/locker.rb', line 9

def initialize(cache_store = DynamicLinks.configuration.cache_store)
  @cache_store = cache_store
end

Instance Attribute Details

#cache_storeObject (readonly)

Returns the value of attribute cache_store.



7
8
9
# File 'lib/dynamic_links/async/locker.rb', line 7

def cache_store
  @cache_store
end

Instance Method Details

#generate_lock_key(client, url) ⇒ Object



13
14
15
# File 'lib/dynamic_links/async/locker.rb', line 13

def generate_lock_key(client, url)
  "lock:shorten_url#{client.id}:#{url_to_lock_key(url)}"
end

#lock_if_absent(lock_key, expires_in: 60, &block) ⇒ Boolean

Acquires a lock for the given key and executes the block if lock is acquired. This method won’t release the lock after block execution. We release the lock in the job after the job is done.

Parameters:

  • lock_key, (String)

    it’s better to use generate_lock_key method to generate lock_key

  • expires_in, (Integer)

    default is 60 seconds

  • block, (Block)

    the block to be executed if lock is acquired

Returns:

  • (Boolean)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/dynamic_links/async/locker.rb', line 28

def lock_if_absent(lock_key, expires_in: 60, &block)
  is_locked = false
  begin
    is_locked = cache_store.increment(lock_key, 1, expires_in: expires_in) == 1
    yield if is_locked && block_given?

    unless is_locked
      DynamicLinks::Logger.log_info "Unable to acquire lock for key: #{lock_key}"
    end
  rescue => e
    DynamicLinks::Logger.log_error("Locking error: #{e.message}")
    raise e
  end

  is_locked
end

#locked?(lock_key) ⇒ Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/dynamic_links/async/locker.rb', line 17

def locked?(lock_key)
  cache_store.exist?(lock_key)
end

#unlock(lock_key) ⇒ Boolean

Deletes an entry in the cache. Returns true if an entry is deleted and false otherwise.

Returns:

  • (Boolean)

Raises:



47
48
49
50
51
# File 'lib/dynamic_links/async/locker.rb', line 47

def unlock(lock_key)
  deleted = cache_store.delete(lock_key)
  raise LockReleaseError, "Unable to release lock for key: #{lock_key}" unless deleted
  deleted
end