139 lines
3.2 KiB
TypeScript
139 lines
3.2 KiB
TypeScript
import { Monitor, Notification } from '@prisma/client';
|
|
import { prisma } from '../_client.js';
|
|
import { MonitorRunner } from './runner.js';
|
|
import { logger } from '../../utils/logger.js';
|
|
|
|
export type MonitorUpsertData = Pick<
|
|
Monitor,
|
|
'workspaceId' | 'name' | 'type' | 'interval' | 'maxRetries' | 'trendingMode'
|
|
> & {
|
|
id?: string;
|
|
active?: boolean;
|
|
notificationIds?: string[];
|
|
payload: Record<string, any>;
|
|
};
|
|
|
|
type MonitorWithNotification = Monitor & { notifications: Notification[] };
|
|
|
|
export class MonitorManager {
|
|
private monitorRunner: Record<string, MonitorRunner> = {};
|
|
private isStarted = false;
|
|
|
|
/**
|
|
* create or update
|
|
*/
|
|
async upsert(data: MonitorUpsertData): Promise<MonitorWithNotification> {
|
|
let monitor: MonitorWithNotification;
|
|
const { id, workspaceId, notificationIds = [], ...others } = data;
|
|
if (id) {
|
|
// update
|
|
monitor = await prisma.monitor.update({
|
|
where: {
|
|
id,
|
|
workspaceId,
|
|
},
|
|
data: {
|
|
...others,
|
|
notifications: {
|
|
set: notificationIds.map((id) => ({ id })),
|
|
},
|
|
},
|
|
include: {
|
|
notifications: true,
|
|
},
|
|
});
|
|
} else {
|
|
// create
|
|
monitor = await prisma.monitor.create({
|
|
data: {
|
|
...others,
|
|
workspaceId,
|
|
notifications: {
|
|
connect: notificationIds.map((id) => ({ id })),
|
|
},
|
|
},
|
|
include: {
|
|
notifications: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
if (this.monitorRunner[monitor.id]) {
|
|
// Stop and remove old
|
|
this.monitorRunner[monitor.id].stopMonitor();
|
|
delete this.monitorRunner[monitor.id];
|
|
}
|
|
|
|
const runner = (this.monitorRunner[monitor.id] = new MonitorRunner(
|
|
monitor
|
|
));
|
|
runner.startMonitor();
|
|
|
|
return monitor;
|
|
}
|
|
|
|
async delete(workspaceId: string, monitorId: string) {
|
|
const runner = this.getRunner(monitorId);
|
|
if (!runner) {
|
|
throw new Error('This monitor not found');
|
|
}
|
|
|
|
runner.stopMonitor();
|
|
delete this.monitorRunner[monitorId];
|
|
|
|
return prisma.monitor.delete({
|
|
where: {
|
|
workspaceId,
|
|
id: monitorId,
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get and start all monitors
|
|
*/
|
|
async startAll() {
|
|
if (this.isStarted === true) {
|
|
logger.warn('MonitorManager.startAll should only call once, skipped.');
|
|
return;
|
|
}
|
|
|
|
this.isStarted = true;
|
|
|
|
const monitors = await prisma.monitor.findMany({
|
|
where: {
|
|
active: true,
|
|
},
|
|
include: {
|
|
notifications: true,
|
|
},
|
|
});
|
|
|
|
Promise.all(
|
|
monitors.map(async (m) => {
|
|
try {
|
|
const runner = new MonitorRunner(m);
|
|
this.monitorRunner[m.id] = runner;
|
|
await runner.startMonitor();
|
|
} catch (err) {
|
|
logger.error('Start monitor error:', String(err));
|
|
}
|
|
})
|
|
).then(() => {
|
|
logger.info('All monitor has been begin.');
|
|
});
|
|
}
|
|
|
|
getRunner(monitorId: string): MonitorRunner | undefined {
|
|
return this.monitorRunner[monitorId];
|
|
}
|
|
|
|
createRunner(monitor: MonitorWithNotification) {
|
|
const runner = (this.monitorRunner[monitor.id] = new MonitorRunner(
|
|
monitor
|
|
));
|
|
|
|
return runner;
|
|
}
|
|
}
|