mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
feat: locking and retry in FB message parsing (#7701)
This commit is contained in:
@@ -7,11 +7,12 @@ module Redis::Alfred
|
||||
# key operations
|
||||
|
||||
# set a value in redis
|
||||
def set(key, value)
|
||||
$alfred.with { |conn| conn.set(key, value) }
|
||||
def set(key, value, nx: false, ex: false) # rubocop:disable Naming/MethodParameterName
|
||||
$alfred.with { |conn| conn.set(key, value, nx: nx, ex: ex) }
|
||||
end
|
||||
|
||||
# set a key with expiry period
|
||||
# TODO: Deprecate this method, use set with ex: 1.day instead
|
||||
def setex(key, value, expiry = 1.day)
|
||||
$alfred.with { |conn| conn.setex(key, expiry, value) }
|
||||
end
|
||||
@@ -30,6 +31,10 @@ module Redis::Alfred
|
||||
$alfred.with { |conn| conn.incr(key) }
|
||||
end
|
||||
|
||||
def exists?(key)
|
||||
$alfred.with { |conn| conn.exists?(key) }
|
||||
end
|
||||
|
||||
# list operations
|
||||
|
||||
def llen(key)
|
||||
|
||||
63
lib/redis/lock_manager.rb
Normal file
63
lib/redis/lock_manager.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
# Redis::LockManager provides a simple mechanism to handle distributed locks using Redis.
|
||||
# This class ensures that only one instance of a given operation runs at a given time across all processes/nodes.
|
||||
# It uses the $alfred Redis namespace for all its operations.
|
||||
#
|
||||
# Example Usage:
|
||||
#
|
||||
# lock_manager = Redis::LockManager.new
|
||||
#
|
||||
# if lock_manager.lock("some_key")
|
||||
# # Critical code that should not be run concurrently
|
||||
# lock_manager.unlock("some_key")
|
||||
# end
|
||||
#
|
||||
class Redis::LockManager
|
||||
# Default lock timeout set to 5 seconds. This means that if the lock isn't released
|
||||
# within 5 seconds, it will automatically expire.
|
||||
# This helps to avoid deadlocks in case the process holding the lock crashes or fails to release it.
|
||||
LOCK_TIMEOUT = 5.seconds
|
||||
|
||||
# Attempts to acquire a lock for the given key.
|
||||
#
|
||||
# If the lock is successfully acquired, the method returns true. If the key is
|
||||
# already locked or if any other error occurs, it returns false.
|
||||
#
|
||||
# === Parameters
|
||||
# * +key+ - The key for which the lock is to be acquired.
|
||||
# * +timeout+ - Duration in seconds for which the lock is valid. Defaults to +LOCK_TIMEOUT+.
|
||||
#
|
||||
# === Returns
|
||||
# * +true+ if the lock was successfully acquired.
|
||||
# * +false+ if the lock was not acquired.
|
||||
def lock(key, timeout = LOCK_TIMEOUT)
|
||||
value = Time.now.to_f.to_s
|
||||
# nx: true means set the key only if it does not exist
|
||||
Redis::Alfred.set(key, value, nx: true, ex: timeout) ? true : false
|
||||
end
|
||||
|
||||
# Releases a lock for the given key.
|
||||
#
|
||||
# === Parameters
|
||||
# * +key+ - The key for which the lock is to be released.
|
||||
#
|
||||
# === Returns
|
||||
# * +true+ indicating the lock release operation was initiated.
|
||||
#
|
||||
# Note: If the key wasn't locked, this operation will have no effect.
|
||||
def unlock(key)
|
||||
Redis::Alfred.delete(key)
|
||||
true
|
||||
end
|
||||
|
||||
# Checks if the given key is currently locked.
|
||||
#
|
||||
# === Parameters
|
||||
# * +key+ - The key to check.
|
||||
#
|
||||
# === Returns
|
||||
# * +true+ if the key is locked.
|
||||
# * +false+ otherwise.
|
||||
def locked?(key)
|
||||
Redis::Alfred.exists?(key)
|
||||
end
|
||||
end
|
||||
@@ -33,4 +33,8 @@ module Redis::RedisKeys
|
||||
MESSAGE_SOURCE_KEY = 'MESSAGE_SOURCE_KEY::%<id>s'.freeze
|
||||
CUSTOM_FILTER_RECORDS_COUNT_KEY = 'CUSTOM_FILTER::%<account_id>d::%<user_id>d::%<filter_id>d'.freeze
|
||||
OPENAI_CONVERSATION_KEY = 'OPEN_AI_CONVERSATION_KEY::%<event_name>s::%<conversation_id>d::%<updated_at>d'.freeze
|
||||
|
||||
## Sempahores / Locks
|
||||
# We don't want to process messages from the same sender concurrently to prevent creating double conversations
|
||||
FACEBOOK_MESSAGE_MUTEX = 'FB_MESSAGE_CREATE_LOCK::%<sender_id>s::%<recipient_id>s'.freeze
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user