wikicr/src/lib/lockable.cr

29 lines
792 B
Crystal

# Lockable is an abstract class that provides a function `#transaction!` that
# allows the class to execute some code that requires to do not conflict with
# other operations. It is usually linked with an IO (a file).
abstract class Lockable
abstract def load!
abstract def save!
@[YAML::Field(key: "lock", ignore: true)]
@lock : Mutex = Mutex.new
# Execute some operation on the object, and then save it.
# The content can be loaded before executing the operations optionnaly.
#
# ```
# someLockableObject.transaction(read: true) { |obj| obj.update_operation(...) }
# ```
def transaction!(read = false)
@lock.synchronize do
begin
self.load! if read == true
yield self
ensure
self.save!
self
end
end
end
end