Module: DynamoidLockable::ClassMethods

Defined in:
lib/dynamoid_lockable.rb

Instance Method Summary collapse

Instance Method Details

#ensure_lockable_field(name) ⇒ Object



123
124
125
# File 'lib/dynamoid_lockable.rb', line 123

def ensure_lockable_field(name)
  raise "Lock #{name} unrecognized" unless lockable_fields.key?(name)
end

#key_filter(condition_builder) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/dynamoid_lockable.rb', line 136

def key_filter(condition_builder)
  if range_key
    condition_builder.public_send(hash_key).exists? & condition_builder.public_send(range_key).exists?
  else
    condition_builder.public_send(hash_key).exists?
  end
end

#lock_config(name) ⇒ Object



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

def lock_config(name)
  lockable_fields[name.to_sym]
end

#lockable(lock_name, locker_name: locking_name) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/dynamoid_lockable.rb', line 111

def lockable(lock_name, locker_name: locking_name)
  ensure_lockable_field(lock_name)

  advanced_where do |r|
    key_filter(r) & (
      (r.send("#{lock_name}_locked_by") == locker_name) |
      !r.send("#{lock_name}_locked_until").exists? |
      (r.send("#{lock_name}_locked_until") < Time.now)
    )
  end
end

#lockable_fieldsObject

TODO: Make this inheritance safe



90
91
92
# File 'lib/dynamoid_lockable.rb', line 90

def lockable_fields
  @lockable_fields ||= {}
end

#lockable_fields=(val) ⇒ Object



94
95
96
# File 'lib/dynamoid_lockable.rb', line 94

def lockable_fields=(val)
  @lockable_fields = val
end

#locking_nameObject



85
86
87
# File 'lib/dynamoid_lockable.rb', line 85

def locking_name
  Thread.current[:dynamo_lock_name] ||= SecureRandom.uuid
end

#locks_with(base_field, lock_for: DEFAULT_LOCK_TIME, relock_every: lock_for / 3) ⇒ Object



102
103
104
105
106
107
108
109
# File 'lib/dynamoid_lockable.rb', line 102

def locks_with(base_field, lock_for: DEFAULT_LOCK_TIME, relock_every: lock_for / 3)
  self.lockable_fields = lockable_fields.merge(
    base_field.to_sym => { duration: lock_for, relock_every: relock_every },
  )

  field  "#{base_field}_locked_until".to_sym, :datetime
  field  "#{base_field}_locked_by".to_sym, :string
end

#unlockable(lock_name, locker_name: locking_name) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/dynamoid_lockable.rb', line 127

def unlockable(lock_name, locker_name: locking_name)
  ensure_lockable_field(lock_name)

  advanced_where do |r|
    key_filter(r) &
      (r.send("#{lock_name}_locked_by") == locker_name)
  end
end