ActionHandle
This gem allows distributed locking with data for actions that are asynchoronous, distributed or simply have various state dependent rules.
Usage examples
ActiveJob conflicts
Let's say we have some resource managed by a handle
class ResourceHandle < ActionHandle::Base; end
And two async jobs with different priorities
class NiceToHaveJob
def perform
handle = ResourceHandle.new('resource_name', 'nice')
return unless handle.create
# execution code
handle.expire
end
end
class ImportantJob
def perform
handle = ResourceHandle.new('resource_name', 'vip')
return if handle.value == 'vip'
handle.claim # ignores current owner
# execution code
handle.expire
end
end
NiceToHaveJob
will only perform on free resource, while ImportantJob
will always perform unless another vip
is already performing.
Not so serious story time example
Let's say we have a room and a few users who try to book it
First we define a room handle
class RoomHandle < ActionHandle::Base
prefix :room
ttl 30.minutes
end
Then we create a handle with room number and user
RoomHandle.create(101, 'Tom', 15.minutes)
#=> true
Tom booked this room with a ttl of an hour. Another user tries to do the same
handle = RoomHandle.new(101, 'Jack')
handle.create
#=> false
handle.value
#=> 'Tom'
Jack fails to book the room and sees that Tom is using it so decides to try later. Most of ttl has passed but Tom is still in the room and extends his handle (a pretty dick move considering Jack is waiting)
RoomHandle.renew(101, 'Tom', 1.hour)
#=> true
More than a standart ttl has passed and Jack tries to book again
RoomHandle.create(101, 'Jack')
#=> false
Jack fails to book the room and stays angry on Tom for taking too long and contacts managament. Meaniwhile Tom is done with his things and leaves the room.
RoomHandle.expire(101, 'Tom')
#=> true
Managament decides to excersise their power and kick Tom out, but sees that no one is using the room
RoomHandle.new(101).taken?
#=> false
Installation
Add this line to your application's Gemfile:
gem 'action-handle'
And then execute:
$ bundle
Or install it yourself as:
$ gem install action-handle
Configuration
ActionHandle.configure do
# simply current redis
adapter :redis
# redis with pool
adapter :redis
redis_pool ConnectionPool.new(size: 5, timeout: 3) { Redis.new }
# rails cache
adapter :cache
# adapters directly (for ex. custom adapters)
adapter Adapters::RedisPool.new(
ConnectionPool.new(size: 5, timeout: 3) { Redis.new }
)
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interaction prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/rbviz/action-handle. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the ActionHandle project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.