Skip to content

Comments

Add new mutex strategies#1

Open
jwoodrow wants to merge 21 commits intomasterfrom
alternative_mutex_strategies
Open

Add new mutex strategies#1
jwoodrow wants to merge 21 commits intomasterfrom
alternative_mutex_strategies

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant