fix: Get online status from db when not present in cache [CW-3233] (#9477)

Previously, we returned the static value 'online' when the status was
not present in the Redis cache. This PR changes it to fall back to the
DB value and updates the cache in such cases.

fixes:
https://linear.app/chatwoot/issue/CW-3233/write-a-back-up-for-online-status-in-case-if-redis-keys-are-not
This commit is contained in:
Sojan Jose
2024-05-15 21:23:19 -07:00
committed by GitHub
parent 7b83480979
commit a2d0e60a88
2 changed files with 20 additions and 2 deletions

View File

@@ -57,7 +57,13 @@ class OnlineStatusTracker
return {} if user_ids.blank? return {} if user_ids.blank?
user_availabilities = ::Redis::Alfred.hmget(status_key(account_id), user_ids) user_availabilities = ::Redis::Alfred.hmget(status_key(account_id), user_ids)
user_ids.map.with_index { |id, index| [id, (user_availabilities[index] || 'online')] }.to_h user_ids.map.with_index { |id, index| [id, (user_availabilities[index] || get_availability_from_db(account_id, id))] }.to_h
end
def self.get_availability_from_db(account_id, user_id)
availability = Account.find(account_id).account_users.find_by(user_id: user_id).availability
set_status(account_id, user_id, availability)
availability
end end
def self.get_available_user_ids(account_id) def self.get_available_user_ids(account_id)

View File

@@ -9,10 +9,11 @@ describe OnlineStatusTracker do
context 'when get_available_users' do context 'when get_available_users' do
before do before do
described_class.update_presence(account.id, 'User', user1.id) described_class.update_presence(account.id, 'User', user1.id)
described_class.update_presence(account.id, 'User', user2.id)
end end
it 'returns only the online user ids with presence' do it 'returns only the online user ids with presence' do
expect(described_class.get_available_users(account.id).keys).to contain_exactly(user1.id.to_s) expect(described_class.get_available_users(account.id).keys).to contain_exactly(user1.id.to_s, user2.id.to_s)
expect(described_class.get_available_users(account.id).values).not_to include(user3.id) expect(described_class.get_available_users(account.id).values).not_to include(user3.id)
end end
@@ -20,6 +21,17 @@ describe OnlineStatusTracker do
user2.account_users.first.update(auto_offline: false) user2.account_users.first.update(auto_offline: false)
expect(described_class.get_available_users(account.id).keys).to contain_exactly(user1.id.to_s, user2.id.to_s) expect(described_class.get_available_users(account.id).keys).to contain_exactly(user1.id.to_s, user2.id.to_s)
end end
it 'returns the availability from the db if it is not present in redis and set it in redis' do
user2.account_users.find_by(account_id: account.id).update!(availability: 'offline')
# clear the redis cache to ensure values are fetched from db
Redis::Alfred.delete(format(Redis::Alfred::ONLINE_STATUS, account_id: account.id))
expect(described_class.get_available_users(account.id)[user1.id.to_s]).to eq('online')
expect(described_class.get_available_users(account.id)[user2.id.to_s]).to eq('offline')
# ensure online status is also set
expect(Redis::Alfred.hmget(format(Redis::Alfred::ONLINE_STATUS, account_id: account.id),
[user1.id.to_s, user2.id.to_s])).to eq(%w[online offline])
end
end end
context 'when get_available_contacts' do context 'when get_available_contacts' do