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(obj, method_id, options = {}, &blk) ⇒ Lock

Returns a new instance of Lock.



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/lock_method/lock.rb', line 42

def initialize(obj, method_id, options = {}, &blk)
  @mutex = ::Mutex.new
  @obj = obj
  @method_id = method_id
  @blk = blk
  options = options.symbolize_keys
  @ttl = options[:ttl]
  @args = options[:args]
  @spin = options[:spin]
  @original_method_id = options[:original_method_id]
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



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

def args
  @args
end

#blkObject (readonly)

Returns the value of attribute blk.



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

def blk
  @blk
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.



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

def original_method_id
  @original_method_id
end

Class Method Details

.find(cache_key) ⇒ Object



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

def find(cache_key)
  LockMethod.config.storage.get cache_key
end

.klass_name(obj) ⇒ Object



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

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



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

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

.method_signature(obj, method_id) ⇒ Object



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

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

.resolve_lock(obj) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/lock_method/lock.rb', line 17

def resolve_lock(obj)
  case obj
  when ::Array
    obj.map do |v|
      resolve_lock v
    end
  when ::Hash
    obj.inject({}) do |memo, (k, v)|
      kk = resolve_lock k
      vv = resolve_lock v
      memo[kk] = vv
      memo
    end
  else
    obj.respond_to?(:as_lock) ? [obj.class.name, obj.as_lock] : obj
  end
end

Instance Method Details

#args_digestObject



72
73
74
75
76
# File 'lib/lock_method/lock.rb', line 72

def args_digest
  @args_digest || @mutex.synchronize do
    @args_digest ||= args.to_a.empty? ? 'empty' : ::Digest::SHA1.hexdigest(::Marshal.dump(Lock.resolve_lock(args)))
  end
end

#cache_keyObject



90
91
92
93
94
95
96
# File 'lib/lock_method/lock.rb', line 90

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

#call_and_lockObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/lock_method/lock.rb', line 106

def call_and_lock
  while locked? and spin?
    ::Kernel.sleep 0.5
  end
  if locked?
    raise Locked
  else
    begin
      save
      obj.send(*([original_method_id]+args), &blk)
    ensure
      delete
    end
  end
end

#deleteObject



78
79
80
# File 'lib/lock_method/lock.rb', line 78

def delete
  LockMethod.config.storage.delete cache_key
end

#locked?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/lock_method/lock.rb', line 86

def locked?
  !!Lock.find(cache_key)
end

#marshal_dumpObject



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

def marshal_dump
  []
end

#marshal_load(source) ⇒ Object



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

def marshal_load(source)
  # nothing
end

#method_signatureObject



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

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

#obj_digestObject



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

def obj_digest
  @obj_digest || @mutex.synchronize do
    @obj_digest ||= ::Digest::SHA1.hexdigest(::Marshal.dump(Lock.resolve_lock(obj)))
  end
end

#saveObject



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

def save
  LockMethod.config.storage.set cache_key, self, ttl
end

#spin?Boolean

Returns:

  • (Boolean)


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

def spin?
  @spin == true
end

#ttlObject



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

def ttl
  @ttl ||= LockMethod.config.default_ttl
end