Skip to content

Add new mutex strategies #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open

Conversation

jwoodrow
Copy link

@jwoodrow jwoodrow commented Mar 24, 2025

Add new strategies to RedisMutex

  • concurrent: Prevent concurrent executions of the block provided, once the block ends, release of the mutex "lock" juste like "standard"
    • When you think about it, the "standard" implementation of redis-mutex is a concurrency restriction of 1
  • cumulative: Prevent a block from being executed too many times over a slidingperiod of time (sliding window looking back expire seconds)
  • windowed: Prevent a block from being executed too many times over a fixed period of time (at the end of expire seconds the execution counter would get reset to 0

Try to make everything backwards compatible by making concurrent strategy and limit 1 the default for the 2 new options introduced

  • limit: How many concurrent block executions do you want to limit yourself to (default 1)
  • type: The type of mutex strategy you wish to use (default concurrent [cumulative, windowed])

Also for easier contribution:

  • Added github action matrix workflow to run CI (github actions is free for public repositories so might as well use it)
  • Added a Dockerfile to run dev containers for each ruby version you might have issues in the CI with (I know I did)
  • In CI, just use the redis that's provided by env variables instead of going for 15 all the time

Still need to add some concurrent/cumulative/windowed specific specs but this currently makes it so the specs work without the need to update them


Here are some simple testing scripts to see how each of these strategies work (adding them as I go)

concurrent + limit > 1
require 'redis-mutex'
RedisClassy.redis = Redis.new

RedisMutex.with_lock('my_lock', limit: 2, block: 2) do
  begin
    puts 'I have the lock! 1'
    RedisMutex.with_lock('my_lock', limit: 2, block: 2) do
      begin
        puts 'I have the lock! 2'
        RedisMutex.with_lock('my_lock', limit: 2, block: 2) do
          begin
            puts 'I have the lock! 3'
          rescue RedisMutex::LockError
            puts 'I could not get the lock 3'
          end
        end
      rescue RedisMutex::LockError
        puts 'I could not get the lock 2'
      end
    end
  rescue RedisMutex::LockError
    puts 'I could not get the lock 1'
  end
end
# => I have the lock! 1
# => I have the lock! 2
# ... 2 seconds pass
# => I could not get the lock 3

@jwoodrow jwoodrow self-assigned this Mar 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant