LoginSignup
10
1

More than 3 years have passed since last update.

Railsで排他制御

Posted at

model以外で特定の処理にロックをかけたい事象が発生したので、その時の対応です。

module Lockable
  extend ActiveSupport::Concern

  class UnableLockError < StandardError; end

  KEY_PREFIX = 'lock/'

  def with_lock(key, expire = 30.seconds)
    real_key = "#{KEY_PREFIX}#{key}"
    value = SecureRandom.hex(10)

    raise UnableLockError unless lock(real_key, value, expire)

    begin
      yield
    ensure
      unlock(real_key, value)
    end
  end

  private

  def lock(key, value, expire)
    redis_client.set(key, value, ex: expire, nx: true)
  end

  def unlock(key, value)
    redis_client.del(key) if $redis.get(key) == value
  end

  def redis_client
    $redis
  end
end
def hoge
  with_lock(key) do
    # somthing
  end
rescue Lockable::UnableLockError
  # handle error
end

redisを用いて対応しました。
もしお困りの方がいらっしゃれば...参考にしてくださいmm

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1