Module: Cachext::Features::Lock

Included in:
Client
Defined in:
lib/cachext/features/lock.rb

Constant Summary collapse

TimeoutWaitingForLock =
Class.new(StandardError)

Instance Method Summary collapse

Instance Method Details

#call_block(key, options, &block) ⇒ Object



21
22
23
24
25
# File 'lib/cachext/features/lock.rb', line 21

def call_block key, options, &block
  with_heartbeat_extender key.digest, options.heartbeat_expires do
    super
  end
end

#obtain_lock(key, options) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/cachext/features/lock.rb', line 46

def obtain_lock key, options
  start_time = Time.now

  until lock_info = @config.lock_manager.lock(key.digest, (options.heartbeat_expires * 1000).ceil)
    wait_for_lock key, start_time
  end

  lock_info
end

#read(key, options) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/cachext/features/lock.rb', line 6

def read key, options
  retval = super
  return retval unless retval.nil?

  @lock_info = obtain_lock key, options

  retval = super

  if !retval.nil?
    @config.lock_manager.unlock @lock_info
  end

  retval
end

#wait_for_lock(key, start_time) ⇒ Object



56
57
58
59
60
61
# File 'lib/cachext/features/lock.rb', line 56

def wait_for_lock key, start_time
  sleep rand(0..(@config.max_lock_wait / 2))
  if Time.now - start_time > @config.max_lock_wait
    raise TimeoutWaitingForLock
  end
end

#with_heartbeat_extender(lock_key, heartbeat_expires, &block) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/cachext/features/lock.rb', line 27

def with_heartbeat_extender lock_key, heartbeat_expires, &block
  done = false
  heartbeat_frequency = heartbeat_expires / 2

  Thread.new do
    loop do
      break if done
      sleep heartbeat_frequency
      break if done
      @config.lock_manager.lock lock_key, (heartbeat_expires * 1000).ceil, extend: @lock_info
    end
  end

  block.call
ensure
  @config.lock_manager.unlock @lock_info if @lock_info
  done = true
end