diff --git a/app/models/concerns/account_cache_revalidator.rb b/app/models/concerns/account_cache_revalidator.rb index 32d7500f8..b5ff5a473 100644 --- a/app/models/concerns/account_cache_revalidator.rb +++ b/app/models/concerns/account_cache_revalidator.rb @@ -2,7 +2,7 @@ module AccountCacheRevalidator extend ActiveSupport::Concern included do - after_commit :update_account_cache, on: [:create, :update] + after_commit :update_account_cache, on: [:create, :update, :destroy] end def update_account_cache diff --git a/app/models/concerns/cache_keys.rb b/app/models/concerns/cache_keys.rb index 7a01f0925..3ad9bbadc 100644 --- a/app/models/concerns/cache_keys.rb +++ b/app/models/concerns/cache_keys.rb @@ -4,6 +4,8 @@ module CacheKeys include CacheKeysHelper include Events::Types + CACHE_KEYS_EXPIRY = 72.hours + included do class_attribute :cacheable_models self.cacheable_models = [Label, Inbox, Team] @@ -18,26 +20,26 @@ module CacheKeys keys end - def invalidate_cache_key_for(key) - prefixed_cache_key = get_prefixed_cache_key(id, key) - Redis::Alfred.delete(prefixed_cache_key) - dispatch_cache_update_event - end - def update_cache_key(key) - prefixed_cache_key = get_prefixed_cache_key(id, key) - Redis::Alfred.set(prefixed_cache_key, Time.now.utc.to_i) + update_cache_key_for_account(id, key) dispatch_cache_update_event end def reset_cache_keys self.class.cacheable_models.each do |model| - invalidate_cache_key_for(model.name.underscore) + update_cache_key_for_account(id, model.name.underscore) end + + dispatch_cache_update_event end private + def update_cache_key_for_account(account_id, key) + prefixed_cache_key = get_prefixed_cache_key(account_id, key) + Redis::Alfred.setex(prefixed_cache_key, Time.now.utc.to_i, CACHE_KEYS_EXPIRY) + end + def dispatch_cache_update_event Rails.configuration.dispatcher.dispatch(ACCOUNT_CACHE_INVALIDATED, Time.zone.now, cache_keys: cache_keys, account: self) end diff --git a/spec/controllers/super_admin/accounts_controller_spec.rb b/spec/controllers/super_admin/accounts_controller_spec.rb index ee295472d..63cad0447 100644 --- a/spec/controllers/super_admin/accounts_controller_spec.rb +++ b/spec/controllers/super_admin/accounts_controller_spec.rb @@ -43,10 +43,13 @@ RSpec.describe 'Super Admin accounts API', type: :request do it 'shows the list of accounts' do expect(account.cache_keys.keys).to contain_exactly(:inbox, :label, :team) sign_in(super_admin, scope: :super_admin) + + now_timestamp = Time.now.utc.to_i post "/super_admin/accounts/#{account.id}/reset_cache" expect(response).to have_http_status(:redirect) expect(flash[:notice]).to eq('Cache keys cleared') - expect(account.reload.cache_keys.values.map(&:to_i)).to eq([0, 0, 0]) + + expect(account.reload.cache_keys.values.all? { |v| v.to_i == now_timestamp }).to be(true) end end end diff --git a/spec/models/concerns/cache_keys_spec.rb b/spec/models/concerns/cache_keys_spec.rb index 51d3c8b7a..33f2dc6b7 100644 --- a/spec/models/concerns/cache_keys_spec.rb +++ b/spec/models/concerns/cache_keys_spec.rb @@ -14,6 +14,7 @@ RSpec.describe CacheKeys do before do allow(Redis::Alfred).to receive(:delete) allow(Redis::Alfred).to receive(:set) + allow(Redis::Alfred).to receive(:setex) allow(Rails.configuration.dispatcher).to receive(:dispatch) end @@ -27,28 +28,11 @@ RSpec.describe CacheKeys do end end - describe '#invalidate_cache_key_for' do - it 'deletes the cache key' do - test_model.invalidate_cache_key_for('label') - expect(Redis::Alfred).to have_received(:delete).with('idb-cache-key-account-1-label') - end - - it 'dispatches a cache update event' do - test_model.invalidate_cache_key_for('label') - expect(Rails.configuration.dispatcher).to have_received(:dispatch).with( - CacheKeys::ACCOUNT_CACHE_INVALIDATED, - kind_of(ActiveSupport::TimeWithZone), - cache_keys: test_model.cache_keys, - account: test_model - ) - end - end - describe '#update_cache_key' do it 'updates the cache key' do allow(Time).to receive(:now).and_return(Time.parse('2023-05-29 00:00:00 UTC')) test_model.update_cache_key('label') - expect(Redis::Alfred).to have_received(:set).with('idb-cache-key-account-1-label', Time.now.utc.to_i) + expect(Redis::Alfred).to have_received(:setex).with('idb-cache-key-account-1-label', kind_of(Integer), CacheKeys::CACHE_KEYS_EXPIRY) end it 'dispatches a cache update event' do @@ -66,8 +50,20 @@ RSpec.describe CacheKeys do it 'invalidates all cache keys for cacheable models' do test_model.reset_cache_keys test_model.class.cacheable_models.each do |model| - expect(Redis::Alfred).to have_received(:delete).with("idb-cache-key-account-1-#{model.name.underscore}") + expect(Redis::Alfred).to have_received(:setex).with("idb-cache-key-account-1-#{model.name.underscore}", kind_of(Integer), + CacheKeys::CACHE_KEYS_EXPIRY) end end + + it 'dispatches a cache update event' do + test_model.reset_cache_keys + + expect(Rails.configuration.dispatcher).to have_received(:dispatch).with( + CacheKeys::ACCOUNT_CACHE_INVALIDATED, + kind_of(ActiveSupport::TimeWithZone), + cache_keys: test_model.cache_keys, + account: test_model + ) + end end end diff --git a/spec/models/inbox_spec.rb b/spec/models/inbox_spec.rb index 8bcb6bcd5..2a56d1fbc 100644 --- a/spec/models/inbox_spec.rb +++ b/spec/models/inbox_spec.rb @@ -250,5 +250,15 @@ RSpec.describe Inbox do cache_keys: inbox.account.cache_keys ) end + + it 'updates the cache key after update' do + expect(inbox.account).to receive(:update_cache_key).with('inbox') + inbox.update(name: 'New Name') + end + + it 'updates the cache key after touch' do + expect(inbox.account).to receive(:update_cache_key).with('inbox') + inbox.touch # rubocop:disable Rails/SkipsModelValidations + end end end