execute_locked_block.rb 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Service::ExecuteLockedBlock < Service::Base
  3. REDIS_URL = ENV['REDIS_URL'].presence || 'redis://localhost:6379'
  4. attr_reader :resource, :ttl, :redis_url
  5. def self.locked?(resource, redis_url: REDIS_URL)
  6. dlm = Redlock::Client.new(redis_url)
  7. dlm.locked?(resource)
  8. end
  9. def self.locked!(resource, redis_url: REDIS_URL)
  10. raise(ExecuteLockedBlockError) if locked?(resource, redis_url: redis_url)
  11. end
  12. def self.lock(resource, ttl, redis_url: REDIS_URL)
  13. dlm = Redlock::Client.new(redis_url)
  14. dlm.lock(resource, ttl)
  15. end
  16. def self.unlock(lock_info, redis_url: REDIS_URL)
  17. dlm = Redlock::Client.new(redis_url)
  18. dlm.unlock(lock_info)
  19. end
  20. def self.extend(lock_info, redis_url: REDIS_URL)
  21. dlm = Redlock::Client.new(redis_url)
  22. dlm.lock(nil, nil, extend: lock_info)
  23. end
  24. def initialize(resource, ttl, redis_url: REDIS_URL)
  25. super()
  26. @resource = resource
  27. @ttl = ttl
  28. @redis_url = redis_url
  29. end
  30. def execute(&)
  31. dlm = Redlock::Client.new(redis_url)
  32. dlm.lock(resource, ttl, &)
  33. end
  34. class ExecuteLockedBlockError < StandardError
  35. def initialize(message = __('This resource cannot be locked, because it has already been locked by another process.'))
  36. super(message)
  37. end
  38. end
  39. end