Purge leftover information in my channel table when purging playbooks (#9057)
* Purge leftover information in my channel table when purging playbooks * Add comment * Clear the sync ephemeral store on plugin disable
This commit is contained in:
parent
d653d55cbc
commit
71cec5a3e2
2 changed files with 50 additions and 3 deletions
|
|
@ -4,15 +4,29 @@
|
|||
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {PLAYBOOK_TABLES} from '@playbooks/constants/database';
|
||||
import {getMyChannel} from '@queries/servers/channel';
|
||||
import {querySystemValue} from '@queries/servers/system';
|
||||
import TestHelper from '@test/test_helper';
|
||||
|
||||
import {updateLastPlaybookRunsFetchAt} from './channel';
|
||||
import {setPlaybooksVersion} from './version';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
|
||||
const serverUrl = 'baseHandler.test.com';
|
||||
const channelId = 'channelid';
|
||||
let operator: ServerDataOperator;
|
||||
|
||||
const channel: Channel = TestHelper.fakeChannel({
|
||||
id: channelId,
|
||||
team_id: 'teamid1',
|
||||
});
|
||||
|
||||
const channelMember: ChannelMembership = TestHelper.fakeChannelMember({
|
||||
id: 'id',
|
||||
channel_id: channelId,
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await DatabaseManager.init([serverUrl]);
|
||||
operator = DatabaseManager.serverDatabases[serverUrl]!.operator;
|
||||
|
|
@ -50,6 +64,11 @@ describe('setPlaybooksVersion', () => {
|
|||
|
||||
it('should purge playbooks when version is empty', async () => {
|
||||
const database = operator.database;
|
||||
|
||||
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
||||
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
||||
await updateLastPlaybookRunsFetchAt(serverUrl, channelId, 1234);
|
||||
|
||||
jest.spyOn(database.adapter, 'unsafeExecute').mockImplementation(() => {
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
|
@ -65,10 +84,18 @@ describe('setPlaybooksVersion', () => {
|
|||
[`DELETE FROM ${PLAYBOOK_TABLES.PLAYBOOK_CHECKLIST_ITEM}`, []],
|
||||
],
|
||||
});
|
||||
|
||||
const myChannel = await getMyChannel(operator.database, channelId);
|
||||
expect(myChannel?.lastPlaybookRunsFetchAt).toBe(0);
|
||||
});
|
||||
|
||||
it('should not purge playbooks when version is not empty', async () => {
|
||||
const database = operator.database;
|
||||
|
||||
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
||||
await operator.handleMyChannel({channels: [channel], myChannels: [channelMember], prepareRecordsOnly: false});
|
||||
await updateLastPlaybookRunsFetchAt(serverUrl, channelId, 1234);
|
||||
|
||||
jest.spyOn(database.adapter, 'unsafeExecute').mockImplementation(() => {
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
|
@ -78,6 +105,8 @@ describe('setPlaybooksVersion', () => {
|
|||
expect(data).toBe(true);
|
||||
|
||||
expect(database.adapter.unsafeExecute).not.toHaveBeenCalled();
|
||||
const myChannel = await getMyChannel(operator.database, channelId);
|
||||
expect(myChannel?.lastPlaybookRunsFetchAt).toBe(1234);
|
||||
});
|
||||
|
||||
it('should handle purge playbooks errors', async () => {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import {Q} from '@nozbe/watermelondb';
|
||||
|
||||
import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {PLAYBOOK_TABLES} from '@playbooks/constants/database';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
|
||||
import type {MyChannelModel} from '@database/models/server';
|
||||
|
||||
export const setPlaybooksVersion = async (serverUrl: string, version: string) => {
|
||||
try {
|
||||
|
|
@ -21,6 +26,8 @@ export const setPlaybooksVersion = async (serverUrl: string, version: string) =>
|
|||
if (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
EphemeralStore.clearChannelPlaybooksSynced(serverUrl);
|
||||
}
|
||||
|
||||
return {data: true};
|
||||
|
|
@ -32,14 +39,25 @@ export const setPlaybooksVersion = async (serverUrl: string, version: string) =>
|
|||
const purgePlaybooks = async (serverUrl: string) => {
|
||||
try {
|
||||
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
|
||||
await database.write(() => {
|
||||
return database.adapter.unsafeExecute({
|
||||
const models = await database.collections.get<MyChannelModel>(MM_TABLES.SERVER.MY_CHANNEL).query(Q.where('last_playbook_runs_fetch_at', Q.gt(0)));
|
||||
|
||||
await database.write(async () => {
|
||||
await database.adapter.unsafeExecute({
|
||||
sqls: [
|
||||
[`DELETE FROM ${PLAYBOOK_TABLES.PLAYBOOK_RUN}`, []],
|
||||
[`DELETE FROM ${PLAYBOOK_TABLES.PLAYBOOK_CHECKLIST}`, []],
|
||||
[`DELETE FROM ${PLAYBOOK_TABLES.PLAYBOOK_CHECKLIST_ITEM}`, []],
|
||||
],
|
||||
});
|
||||
|
||||
// Process each model sequentially to prevent overwhelming the event loop with excessive promises
|
||||
// and to avoid overloading the database with concurrent write operations, especially when handling a large number of channels.
|
||||
for await (const model of models) {
|
||||
await model.update((channel) => {
|
||||
channel.lastPlaybookRunsFetchAt = 0;
|
||||
return channel;
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
return {error};
|
||||
|
|
|
|||
Loading…
Reference in a new issue