refactor: remove client-side cache key pulls
This commit is contained in:
@@ -50,12 +50,11 @@ class CacheEnabledApiClient extends ApiClient {
|
||||
return this.getFromNetwork();
|
||||
}
|
||||
|
||||
// Trust the IDB cache. Freshness is maintained by:
|
||||
// - boot-time hydrateStoresFromCache (compares server keys once on boot)
|
||||
// - ActionCable ACCOUNT_CACHE_INVALIDATED broadcasts (live updates)
|
||||
// - ReconnectService.revalidateCaches (on WebSocket reconnect)
|
||||
// Skipping the per-call /cache_keys preflight eliminates N GET requests per
|
||||
// cold settings-page load.
|
||||
// Trust the IDB cache. Freshness is maintained by the
|
||||
// account.cache_invalidated event alone: RoomChannel pushes the cache-key
|
||||
// map on every (re)subscribe — boot and reconnect included — and the
|
||||
// server broadcasts it on every change. Skipping a per-call /cache_keys
|
||||
// preflight eliminates N GET requests per cold settings-page load.
|
||||
const localData = await this.dataManager.get({
|
||||
modelName: this.cacheModelName,
|
||||
});
|
||||
|
||||
@@ -9,13 +9,6 @@ class AccountAPI extends ApiClient {
|
||||
createAccount(data) {
|
||||
return axios.post(`${this.apiVersion}/accounts`, data);
|
||||
}
|
||||
|
||||
async getCacheKeys() {
|
||||
const response = await axios.get(
|
||||
`/api/v1/accounts/${this.accountIdFromRoute}/cache_keys`
|
||||
);
|
||||
return response.data.cache_keys;
|
||||
}
|
||||
}
|
||||
|
||||
export default new AccountAPI();
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
isAInboxViewRoute,
|
||||
isNotificationRoute,
|
||||
} from 'dashboard/helper/routeHelpers';
|
||||
import { dispatchCacheRevalidations } from 'dashboard/helper/CacheHelper/dispatchCacheRevalidations';
|
||||
|
||||
const MAX_DISCONNECT_SECONDS = 10800;
|
||||
|
||||
@@ -99,11 +98,6 @@ class ReconnectService {
|
||||
await this.store.dispatch('notifications/index', { ...filter, page: 1 });
|
||||
};
|
||||
|
||||
revalidateCaches = async () => {
|
||||
const keys = (await this.store.dispatch('accounts/getCacheKeys')) || {};
|
||||
await dispatchCacheRevalidations(this.store, keys);
|
||||
};
|
||||
|
||||
handleRouteSpecificFetch = async () => {
|
||||
const currentRoute = this.router.currentRoute.value.name;
|
||||
if (isAConversationRoute(currentRoute, true)) {
|
||||
@@ -133,9 +127,11 @@ class ReconnectService {
|
||||
this.setConversationLastMessageId();
|
||||
};
|
||||
|
||||
// Cached workspace config needs no explicit revalidation here: ActionCable
|
||||
// auto-resubscribes after a drop, and RoomChannel pushes the cache-key map
|
||||
// on every subscribe via the account.cache_invalidated event.
|
||||
onReconnect = async () => {
|
||||
await this.handleRouteSpecificFetch();
|
||||
await this.revalidateCaches();
|
||||
emitter.emit(BUS_EVENTS.WEBSOCKET_RECONNECT_COMPLETED);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -253,54 +253,6 @@ describe('ReconnectService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('revalidateCaches', () => {
|
||||
it('should dispatch revalidate actions for every cacheable model returned by the server', async () => {
|
||||
storeMock.dispatch.mockResolvedValueOnce({
|
||||
label: 'labelKey',
|
||||
inbox: 'inboxKey',
|
||||
team: 'teamKey',
|
||||
canned_response: 'cannedKey',
|
||||
account_user: 'accountUserKey',
|
||||
});
|
||||
await reconnectService.revalidateCaches();
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith('accounts/getCacheKeys');
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith('labels/revalidate', {
|
||||
newKey: 'labelKey',
|
||||
});
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith('inboxes/revalidate', {
|
||||
newKey: 'inboxKey',
|
||||
});
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith('teams/revalidate', {
|
||||
newKey: 'teamKey',
|
||||
});
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith(
|
||||
'revalidateCannedResponses',
|
||||
{ newKey: 'cannedKey' }
|
||||
);
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith('agents/revalidate', {
|
||||
newKey: 'accountUserKey',
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip dispatches for models the server does not yet emit', async () => {
|
||||
storeMock.dispatch.mockResolvedValueOnce({
|
||||
label: 'labelKey',
|
||||
inbox: 'inboxKey',
|
||||
team: 'teamKey',
|
||||
// canned_response / account_user omitted (older server)
|
||||
});
|
||||
await reconnectService.revalidateCaches();
|
||||
expect(storeMock.dispatch).not.toHaveBeenCalledWith(
|
||||
'revalidateCannedResponses',
|
||||
expect.anything()
|
||||
);
|
||||
expect(storeMock.dispatch).not.toHaveBeenCalledWith(
|
||||
'agents/revalidate',
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleRouteSpecificFetch', () => {
|
||||
it('should fetch conversations and messages if current route is a conversation route', async () => {
|
||||
isAConversationRoute.mockReturnValue(true);
|
||||
@@ -362,12 +314,10 @@ describe('ReconnectService', () => {
|
||||
});
|
||||
|
||||
describe('onReconnect', () => {
|
||||
it('should handle route-specific fetch, revalidate caches, and emit WEBSOCKET_RECONNECT_COMPLETED event', async () => {
|
||||
it('should handle route-specific fetch and emit WEBSOCKET_RECONNECT_COMPLETED event', async () => {
|
||||
reconnectService.handleRouteSpecificFetch = vi.fn();
|
||||
reconnectService.revalidateCaches = vi.fn();
|
||||
await reconnectService.onReconnect();
|
||||
expect(reconnectService.handleRouteSpecificFetch).toHaveBeenCalled();
|
||||
expect(reconnectService.revalidateCaches).toHaveBeenCalled();
|
||||
expect(emitter.emit).toHaveBeenCalledWith(
|
||||
BUS_EVENTS.WEBSOCKET_RECONNECT_COMPLETED
|
||||
);
|
||||
|
||||
@@ -163,10 +163,6 @@ export const actions = {
|
||||
commit(types.default.SET_ACCOUNT_UI_FLAG, { isFetchingLimits: false });
|
||||
}
|
||||
},
|
||||
|
||||
getCacheKeys: async () => {
|
||||
return AccountAPI.getCacheKeys();
|
||||
},
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
|
||||
@@ -14,9 +14,6 @@ class BaseActionCableConnector {
|
||||
) {
|
||||
const websocketURL = websocketHost ? `${websocketHost}/cable` : undefined;
|
||||
|
||||
this.connected = new Promise(resolve => {
|
||||
this.resolveConnected = resolve;
|
||||
});
|
||||
this.consumer = createConsumer(websocketURL);
|
||||
this.subscription = this.consumer.subscriptions.create(
|
||||
{
|
||||
@@ -29,10 +26,6 @@ class BaseActionCableConnector {
|
||||
updatePresence() {
|
||||
this.perform('update_presence');
|
||||
},
|
||||
connected: () => {
|
||||
this.resolveConnected();
|
||||
this.onConnected();
|
||||
},
|
||||
received: this.onReceived,
|
||||
disconnected: () => {
|
||||
BaseActionCableConnector.isDisconnected = true;
|
||||
@@ -81,9 +74,6 @@ class BaseActionCableConnector {
|
||||
}, RECONNECT_INTERVAL);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onConnected = () => {};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onReconnect = () => {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user