feat: cache counts
This commit is contained in:
@@ -32,13 +32,15 @@ class ConversationFinder
|
||||
def initialize(current_user, params)
|
||||
@current_user = current_user
|
||||
@current_account = current_user.account
|
||||
@is_admin = current_account.account_users.find_by(user_id: current_user.id)&.administrator?
|
||||
@params = params
|
||||
end
|
||||
|
||||
def perform
|
||||
set_up
|
||||
|
||||
mine_count, unassigned_count, all_count, = set_count_for_all_conversations
|
||||
mine_count = compute_mine_count
|
||||
unassigned_count, all_count = compute_unassigned_and_all_count
|
||||
assigned_count = all_count - unassigned_count
|
||||
|
||||
filter_by_assignee_type
|
||||
@@ -86,7 +88,8 @@ class ConversationFinder
|
||||
end
|
||||
|
||||
def find_all_conversations
|
||||
@conversations = current_account.conversations.where(inbox_id: @inbox_ids)
|
||||
@conversations = current_account.conversations
|
||||
@conversations = @conversations.where(inbox_id: @inbox_ids) unless @is_admin
|
||||
filter_by_conversation_type if params[:conversation_type]
|
||||
@conversations
|
||||
end
|
||||
@@ -151,12 +154,53 @@ class ConversationFinder
|
||||
@conversations = @conversations.where(contact_inboxes: { source_id: params[:source_id] })
|
||||
end
|
||||
|
||||
def set_count_for_all_conversations
|
||||
[
|
||||
@conversations.assigned_to(current_user).count,
|
||||
@conversations.unassigned.count,
|
||||
@conversations.count
|
||||
]
|
||||
def compute_mine_count
|
||||
# Mine count is always computed fresh, never cached
|
||||
@conversations.assigned_to(current_user).count
|
||||
end
|
||||
|
||||
def compute_unassigned_and_all_count
|
||||
return compute_unassigned_and_all_count_without_cache if additional_filters? || !should_cache?
|
||||
|
||||
cached_counts = ::Redis::Alfred.get(cache_key)
|
||||
if cached_counts.present?
|
||||
begin
|
||||
return JSON.parse(cached_counts)
|
||||
rescue JSON::ParserError
|
||||
compute_unassigned_and_all_count_without_cache
|
||||
end
|
||||
end
|
||||
|
||||
counts = compute_unassigned_and_all_count_without_cache
|
||||
::Redis::Alfred.setex(cache_key, counts, cache_expiry(counts[0]))
|
||||
|
||||
counts
|
||||
end
|
||||
|
||||
def compute_unassigned_and_all_count_without_cache
|
||||
unassigned_count = @conversations.unassigned.count
|
||||
all_count = @conversations.count
|
||||
[unassigned_count, all_count]
|
||||
end
|
||||
|
||||
def should_cache?
|
||||
true
|
||||
end
|
||||
|
||||
def cache_key
|
||||
@cache_key ||= format(::Redis::Alfred::CONVERSATION_COUNTS, inbox_ids: @inbox_ids.sort.join('-'), status: params[:status] || DEFAULT_STATUS)
|
||||
end
|
||||
|
||||
def cache_expiry(unassigned_count)
|
||||
return 5.seconds if unassigned_count < 100
|
||||
return 10.seconds if unassigned_count < 200
|
||||
return 15.seconds if unassigned_count < 500
|
||||
|
||||
20.seconds
|
||||
end
|
||||
|
||||
def additional_filters?
|
||||
params[:q].present? || params[:conversation_type].present? || params[:team_id].present? || params[:labels].present? || params[:source_id].present?
|
||||
end
|
||||
|
||||
def current_page
|
||||
|
||||
@@ -41,4 +41,7 @@ module Redis::RedisKeys
|
||||
IG_MESSAGE_MUTEX = 'IG_MESSAGE_CREATE_LOCK::%<sender_id>s::%<ig_account_id>s'.freeze
|
||||
SLACK_MESSAGE_MUTEX = 'SLACK_MESSAGE_LOCK::%<conversation_id>s::%<reference_id>s'.freeze
|
||||
EMAIL_MESSAGE_MUTEX = 'EMAIL_CHANNEL_LOCK::%<inbox_id>s'.freeze
|
||||
|
||||
# Cache for storing conversation meta counts
|
||||
CONVERSATION_COUNTS = 'CONVERSATION::COUNTS::%<inbox_ids>s::%<status>s'.freeze
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user