Class: LockMethod::Lock

Inherits:
Object
  • Object
show all
Defined in:
lib/lock_method/lock.rb

Overview

:nodoc: all

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Lock

Returns a new instance of Lock.



30
31
32
33
34
# File 'lib/lock_method/lock.rb', line 30

def initialize(options = {})
  options.each do |k, v|
    instance_variable_set "@#{k}", v
  end
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



39
40
41
# File 'lib/lock_method/lock.rb', line 39

def args
  @args
end

#method_idObject (readonly)

Returns the value of attribute method_id.



37
38
39
# File 'lib/lock_method/lock.rb', line 37

def method_id
  @method_id
end

#objObject (readonly)

Returns the value of attribute obj.



36
37
38
# File 'lib/lock_method/lock.rb', line 36

def obj
  @obj
end

#original_method_idObject (readonly)

Returns the value of attribute original_method_id.



38
39
40
# File 'lib/lock_method/lock.rb', line 38

def original_method_id
  @original_method_id
end

Class Method Details

.find(cache_key) ⇒ Object



4
5
6
7
8
# File 'lib/lock_method/lock.rb', line 4

def find(cache_key)
  if hsh = Config.instance.storage.get(cache_key)
    new hsh
  end
end

.klass_name(obj) ⇒ Object



9
10
11
# File 'lib/lock_method/lock.rb', line 9

def klass_name(obj)
  (obj.is_a?(::Class) or obj.is_a?(::Module)) ? obj.to_s : obj.class.to_s
end

.method_delimiter(obj) ⇒ Object



12
13
14
# File 'lib/lock_method/lock.rb', line 12

def method_delimiter(obj)
  (obj.is_a?(::Class) or obj.is_a?(::Module)) ? '.' : '#'
end

.method_signature(obj, method_id) ⇒ Object



15
16
17
# File 'lib/lock_method/lock.rb', line 15

def method_signature(obj, method_id)
  [ klass_name(obj), method_id ].join method_delimiter(obj)
end

.process_alive?(pid) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
21
22
# File 'lib/lock_method/lock.rb', line 18

def process_alive?(pid)
  ::Process.kill 0, pid
rescue ::Errno::ESRCH
  false
end

.thread_alive?(thread_object_id) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
26
27
# File 'lib/lock_method/lock.rb', line 23

def thread_alive?(thread_object_id)
  if thr = ::Thread.list.detect { |t| t.object_id == thread_object_id }
    thr.status == 'sleep' or thr.status == 'run'
  end
end

Instance Method Details

#cache_keyObject



87
88
89
90
91
92
93
# File 'lib/lock_method/lock.rb', line 87

def cache_key
  if obj.is_a?(::Class) or obj.is_a?(::Module)
    [ 'LockMethod', 'Lock', method_signature ].join ','
  else
    [ 'LockMethod', 'Lock', method_signature, obj_hash ].join ','
  end
end

#call_original_methodObject



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/lock_method/lock.rb', line 115

def call_original_method
  if locked?
    raise Locked
  else
    begin
      save
      obj.send original_method_id, *args
    ensure
      delete
    end
  end
end

#deleteObject



61
62
63
# File 'lib/lock_method/lock.rb', line 61

def delete
  Config.instance.storage.delete cache_key
end

#expired?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/lock_method/lock.rb', line 103

def expired?
  expiry.to_f < ::Time.now.to_f
end

#expiryObject



57
58
59
# File 'lib/lock_method/lock.rb', line 57

def expiry
  @expiry ||= ::Time.now + ttl
end

#in_force?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/lock_method/lock.rb', line 99

def in_force?
  not expired? and process_and_thread_still_exist?
end

#locked?Boolean

Returns:

  • (Boolean)


81
82
83
84
85
# File 'lib/lock_method/lock.rb', line 81

def locked?
  if existing_lock = Lock.find(cache_key)
    existing_lock.in_force?
  end
end

#method_signatureObject



41
42
43
# File 'lib/lock_method/lock.rb', line 41

def method_signature
  @method_signature ||= Lock.method_signature(obj, method_id)
end

#obj_hashObject



95
96
97
# File 'lib/lock_method/lock.rb', line 95

def obj_hash
  @obj_hash ||= obj.respond_to?(:method_lock_hash) ? obj.method_lock_hash : obj.hash
end

#pidObject



49
50
51
# File 'lib/lock_method/lock.rb', line 49

def pid
  @pid ||= ::Process.pid
end

#process_and_thread_still_exist?Boolean

Returns:

  • (Boolean)


107
108
109
110
111
112
113
# File 'lib/lock_method/lock.rb', line 107

def process_and_thread_still_exist?
  if pid == ::Process.pid
    Lock.thread_alive? thread_object_id
  else
    Lock.process_alive? pid
  end
end

#saveObject



65
66
67
68
69
70
71
72
# File 'lib/lock_method/lock.rb', line 65

def save
  # make sure these are set
  self.pid
  self.thread_object_id
  self.expiry
  # --
  Config.instance.storage.set cache_key, to_hash, ttl
end

#thread_object_idObject



53
54
55
# File 'lib/lock_method/lock.rb', line 53

def thread_object_id
  @thread_object_id ||= ::Thread.current.object_id
end

#to_hashObject



74
75
76
77
78
79
# File 'lib/lock_method/lock.rb', line 74

def to_hash
  instance_variables.inject({}) do |memo, ivar_name|
    memo[ivar_name.to_s.sub('@', '')] = instance_variable_get ivar_name
    memo
  end
end

#ttlObject



45
46
47
# File 'lib/lock_method/lock.rb', line 45

def ttl
  @ttl ||= Config.instance.default_ttl
end