Skip to content

Commit

Permalink
refactor: Improve Sentinel logic and improve debouncing
Browse files Browse the repository at this point in the history
  • Loading branch information
PartMan7 committed Oct 29, 2024
1 parent 2a4e2b3 commit dc1f3fc
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/database/alts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ export async function getAlts(user: string, limit: number = DEFAULT_ALTS_CAP): P
}

export async function fetchAllAlts(): Promise<Model[]> {
return model.find({}).lean();
return model.find({}).maxTimeMS(30_000).lean();
}
7 changes: 2 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ import '@/globals';
import PS from '@/ps';
import Discord from '@/discord';
import Web from '@/web';
import { connect } from '@/database';
import '@/sentinel';

global.PS = PS;
global.Discord = Discord;
global.Web = Web;

import { connect } from '@/database';
connect().then(() => log('Connected to the database!'));

import { emitter } from '@/sentinel';

export default emitter;
17 changes: 0 additions & 17 deletions src/sentinel/client.ts

This file was deleted.

20 changes: 19 additions & 1 deletion src/sentinel/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
import createSentinel from '@/sentinel/sentinel';
export const { emitter, sentinel } = createSentinel();
const { emitter, sentinel } = createSentinel();

emitter.on('trigger', (label, file) => {
log(`Triggered ${label} reload from ${file}`);
});

emitter.on('start', (label, files) => {
log(`Started ${label} reload with ${files.join(', ')}`);
});

emitter.on('complete', (label, files) => {
log(`Completed ${label} reload with ${files.join(', ')}`);
});

emitter.on('error', (err, label, files) => {
log(`Ran into an error while reloading ${label} for ${files.join(', ')}`, err);
});

export { emitter, sentinel };
62 changes: 53 additions & 9 deletions src/sentinel/sentinel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,66 @@ import { debounce } from '@/utils/debounce';

import { reloadCommands } from '@/ps/loaders/commands';

type Listener = { pattern: RegExp; reload: (filepath: string) => void };
type ListenerType = 'commands';
type Register = { label: ListenerType; pattern: RegExp; reload: (filepaths: string[]) => Promise<void> | void; debounce?: number };
type Listener = { label: ListenerType; pattern: RegExp; reload: (filepaths: string) => Promise<void> | void };

interface EmitterEvents {
trigger: [label: ListenerType, file: string];
start: [label: ListenerType, files: string[]];
complete: [label: ListenerType, files: string[]];
error: [error: Error, label: ListenerType, files: string[]];
}

class Emitter extends EventEmitter {
emit<K extends keyof EmitterEvents>(event: K, ...args: EmitterEvents[K]): boolean {
return super.emit(event, ...args);
}
on<K extends keyof EmitterEvents>(event: K, listener: (...args: EmitterEvents[K]) => void): this {
return super.on(event, listener);
}
}

export default function createSentinel() {
const listeners: Listener[] = [
const emitter = new Emitter();

const registers: Register[] = [
{
label: 'commands',
pattern: /ps\/commands\//,
reload: async () => {
log('Reloading commands...');
await reloadCommands();
log('Reloaded commands');
},
reload: reloadCommands,
debounce: 1000,
},
].map(listener => ({ pattern: listener.pattern, reload: debounce(listener.reload, listener.debounce) }));
];

const listeners: Listener[] = registers
.map(
// Add debouncing
(listener: Register): Register => {
const start = async (filepaths: string[]) => {
emitter.emit('start', listener.label, filepaths);
try {
await listener.reload(filepaths);
emitter.emit('complete', listener.label, filepaths);
} catch (err) {
emitter.emit('error', err, listener.label, filepaths);
}
};
return {
...listener,
reload: listener.debounce ? debounce(start, listener.debounce) : start,
};
}
)
.map(listener => ({
label: listener.label,
pattern: listener.pattern,
reload: (filepath: string) => {
emitter.emit('trigger', listener.label, filepath);
listener.reload([filepath]);
},
}));

const emitter = new EventEmitter();
const sentinel = chokidar.watch(fsPath('..', 'src'), { ignoreInitial: true });
sentinel.on('all', async (event, filepath) => {
listeners.find(({ pattern }) => pattern.test(filepath))?.reload(filepath);
Expand Down
11 changes: 8 additions & 3 deletions src/utils/debounce.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
export function debounce<T extends (...args: unknown[]) => unknown>(
export function debounce<T extends (...args: unknown[][]) => unknown>(
callback: T,
debounceInterval: number
): (...args: Parameters<T>) => void {
let debounceTimer: NodeJS.Timeout;
return (...args) => {
let args: Parameters<T> | [] = [];
return (...newArgs) => {
args = newArgs.map((newArg, i) => [...(args[i] ?? []), ...newArg]) as Parameters<T>;
if (debounceTimer) clearTimeout(debounceTimer);
debounceTimer = setTimeout(callback, debounceInterval, ...args);
debounceTimer = setTimeout(() => {
callback(...args);
args = [];
}, debounceInterval);
};
}

0 comments on commit dc1f3fc

Please sign in to comment.