Skip to content

Commit

Permalink
Server: Resolves #9931: Add task to delete events older than a week
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienPoupa committed Nov 12, 2024
1 parent 1ed080e commit a796af6
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 10 deletions.
12 changes: 11 additions & 1 deletion packages/server/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const defaultEnvValues: EnvVariables = {
IS_ADMIN_INSTANCE: true,
INSTANCE_NAME: '',

// Maxiumm allowed drift between NTP time and server time. A few
// Maximum allowed drift between NTP time and server time. A few
// milliseconds is normally not an issue unless many clients are modifying
// the same note at the exact same time. But past a certain limit, it might
// mean the server clock is incorrect and should be fixed, as that could
Expand Down Expand Up @@ -118,6 +118,13 @@ const defaultEnvValues: EnvVariables = {
USER_DATA_AUTO_DELETE_ENABLED: false,
USER_DATA_AUTO_DELETE_AFTER_DAYS: 90,

// ==================================================
// Events deletion
// ==================================================

EVENTS_AUTO_DELETE_ENABLED: true,
EVENTS_AUTO_DELETE_AFTER_DAYS: 7,

// ==================================================
// LDAP configuration
// ==================================================
Expand Down Expand Up @@ -210,6 +217,9 @@ export interface EnvVariables {
USER_DATA_AUTO_DELETE_ENABLED: boolean;
USER_DATA_AUTO_DELETE_AFTER_DAYS: number;

EVENTS_AUTO_DELETE_ENABLED: boolean;
EVENTS_AUTO_DELETE_AFTER_DAYS: number;

LDAP_1_ENABLED: boolean;
LDAP_1_USER_AUTO_CREATION: boolean;
LDAP_1_HOST: string;
Expand Down
49 changes: 48 additions & 1 deletion packages/server/src/models/EventModel.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EventType } from '../services/database/types';
import { beforeAllDb, afterAllTests, beforeEachDb, models } from '../utils/testing/testUtils';
import { msleep, Week } from '../utils/time';
import { Month, msleep, Week } from '../utils/time';
import config from '../config.js';

describe('EventModel', () => {

Expand Down Expand Up @@ -85,4 +86,50 @@ describe('EventModel', () => {
jest.useRealTimers();
});

test('should delete events older than a custom interval', async () => {
config().EVENTS_AUTO_DELETE_AFTER_DAYS = 30;
const now = Date.now();
const aMonthAgo = now - Month;
jest.useFakeTimers();

for (const difference of [-10, -5, 0, 5, 10]) {
jest.setSystemTime(aMonthAgo + difference);
await models().event().create(EventType.TaskStarted, 'deleteExpiredTokens');
}

const allEvents = (await models().event().all());
expect(allEvents.length).toBe(5);

jest.setSystemTime(now);
await models().event().deleteOldEvents();

const remainingEvents = (await models().event().all());
expect(remainingEvents.length).toBe(3);

for (const event of remainingEvents) {
expect(event.created_time).toBeGreaterThanOrEqual(aMonthAgo);
}

jest.useRealTimers();
});

test('should not delete old events if config disabled', async () => {
config().EVENTS_AUTO_DELETE_ENABLED = false;
const now = Date.now();
const aWeekAgo = now - Week;
jest.useFakeTimers().setSystemTime(aWeekAgo + 5);
await models().event().create(EventType.TaskStarted, 'deleteExpiredTokens');

const allEvents = (await models().event().all());
expect(allEvents.length).toBe(1);

jest.setSystemTime(now);
await models().event().deleteOldEvents();

const remainingEvents = (await models().event().all());
expect(remainingEvents.length).toBe(1);

jest.useRealTimers();
});

});
15 changes: 14 additions & 1 deletion packages/server/src/models/EventModel.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { Event, EventType } from '../services/database/types';
import BaseModel, { UuidType } from './BaseModel';
import { Day } from '../utils/time';
import { DbConnection } from '../db.js';
import { NewModelFactoryHandler } from './factory.js';
import { Config } from '../utils/types.js';


export default class EventModel extends BaseModel<Event> {

private eventTtl_: number = 7 * Day;
private readonly eventTtl_: number;
private readonly eventAutoDelete_: boolean;

public constructor(db: DbConnection, dbSlave: DbConnection, modelFactory: NewModelFactoryHandler, config: Config) {
super(db, dbSlave, modelFactory, config);
this.eventAutoDelete_ = config.EVENTS_AUTO_DELETE_ENABLED;
this.eventTtl_ = config.EVENTS_AUTO_DELETE_AFTER_DAYS * Day;
}

public get tableName(): string {
return 'events';
Expand Down Expand Up @@ -37,6 +47,9 @@ export default class EventModel extends BaseModel<Event> {
}

public async deleteOldEvents() {
if (!this.eventAutoDelete_) {
return null;
}
const cutOffDate = Date.now() - this.eventTtl_;
return this.withTransaction(async () => {
await this.db(this.tableName)
Expand Down
16 changes: 9 additions & 7 deletions packages/server/src/utils/setupTaskService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,6 @@ export default async function(env: Env, models: Models, config: Config, services
schedule: config.HEARTBEAT_MESSAGE_SCHEDULE,
run: (_models: Models, _services: Services) => logHeartbeatMessage(),
},

{
id: TaskId.DeleteOldEvents,
description: taskIdToLabel(TaskId.DeleteOldEvents),
schedule: '0 0 * * *',
run: (models: Models) => models.event().deleteOldEvents(),
},
];

if (config.USER_DATA_AUTO_DELETE_ENABLED) {
Expand All @@ -100,6 +93,15 @@ export default async function(env: Env, models: Models, config: Config, services
});
}

if (config.EVENTS_AUTO_DELETE_ENABLED) {
tasks.push({
id: TaskId.DeleteOldEvents,
description: taskIdToLabel(TaskId.DeleteOldEvents),
schedule: '0 0 * * *',
run: (models: Models) => models.event().deleteOldEvents(),
});
}

if (config.isJoplinCloud) {
tasks = tasks.concat([
{
Expand Down

0 comments on commit a796af6

Please sign in to comment.