Data sweepers

This commit is contained in:
Erik 2023-07-13 20:15:13 +03:00
parent 4ea7358f64
commit 6f92e9d36c
Signed by: Navy.gif
GPG Key ID: 2532FBBB61C65A68
2 changed files with 42 additions and 6 deletions

View File

@ -1,11 +1,11 @@
import { AbstractUser } from "../src/server/interfaces/index.js"; import { AbstractUser } from '../src/server/interfaces/index.js';
import { LoggerClientOptions } from '@navy.gif/logger'; import { LoggerClientOptions } from '@navy.gif/logger';
import { BrokerOptions, MariaOptions, MongoOptions, ObjectId } from '@navy.gif/wrappers'; import { BrokerOptions, MariaOptions, MongoOptions, ObjectId } from '@navy.gif/wrappers';
import { Request as ExpressRequest, Response as ExpressResponse, NextFunction } from "express"; import { Request as ExpressRequest, Response as ExpressResponse, NextFunction } from 'express';
import http from 'http'; import http from 'http';
import { UploadedFile } from "express-fileupload"; import { UploadedFile } from 'express-fileupload';
import { Session } from "express-session"; import { Session } from 'express-session';
import Role from "../src/server/structures/Role.js"; import Role from '../src/server/structures/Role.js';
/** /**
* TERMINOLOGY * TERMINOLOGY
@ -60,7 +60,8 @@ export type ServerOptions = {
discord: { discord: {
scope?: string[], scope?: string[],
version?: number version?: number
} },
sweeperInterval?: number
} }
export type Permissions = { export type Permissions = {

View File

@ -25,9 +25,12 @@ import { MongoMemory } from './database/index.js';
import { IPCMessage, SignupCode } from '../../@types/Other.js'; import { IPCMessage, SignupCode } from '../../@types/Other.js';
import { DoneCallback } from 'passport'; import { DoneCallback } from 'passport';
import FlagManager from './components/FlagManager.js'; import FlagManager from './components/FlagManager.js';
import { Collection } from '@discordjs/collection';
// const pkg = JSON.parse(readFileSync('../../package.json', { encoding: 'utf8' })); // const pkg = JSON.parse(readFileSync('../../package.json', { encoding: 'utf8' }));
type Sweeper = () => Promise<void> | void
/** /**
* Meant to be deployed behind a proxy (e.g. nginx) instance that takes care of certs and load balancing, trusts the first proxy * Meant to be deployed behind a proxy (e.g. nginx) instance that takes care of certs and load balancing, trusts the first proxy
* *
@ -67,6 +70,9 @@ class Server extends EventEmitter
#logger: LoggerClient; #logger: LoggerClient;
#sweepers: Collection<string, Sweeper>;
#sweeperInterval!: NodeJS.Timer;
// eslint-disable-next-line max-lines-per-function // eslint-disable-next-line max-lines-per-function
constructor (options: ServerOptions) constructor (options: ServerOptions)
{ {
@ -224,6 +230,8 @@ class Server extends EventEmitter
this.#app.use(this.#attachMisc.bind(this) as never); this.#app.use(this.#attachMisc.bind(this) as never);
this.#app.use(this.#logRequest.bind(this) as never); // Logs every request this.#app.use(this.#logRequest.bind(this) as never); // Logs every request
this.#sweepers = new Collection();
process.on('message', this._handleMessage.bind(this)); process.on('message', this._handleMessage.bind(this));
process.on('SIGINT', this.shutdown.bind(this)); process.on('SIGINT', this.shutdown.bind(this));
@ -264,6 +272,12 @@ class Server extends EventEmitter
this.#logger.debug('Registered permissions:'); this.#logger.debug('Registered permissions:');
this.#logger.debug(PermissionManager.DefaultPermissions); this.#logger.debug(PermissionManager.DefaultPermissions);
if (this.shardId === 0)
{
this.#logger.info('Starting sweeper');
this.#sweeperInterval = setInterval(this.#runSweepers.bind(this), this.#options.sweeperInterval ?? 30 * 60 * 1000);
}
this.#logger.status(`Server created, took ${Date.now() - start} ms, listening on port ${this.port}`); this.#logger.status(`Server created, took ${Date.now() - start} ms, listening on port ${this.port}`);
if (process.send) if (process.send)
process.send({ _ready: true }); process.send({ _ready: true });
@ -271,6 +285,25 @@ class Server extends EventEmitter
} }
registerSweeper (name: string, sweeper: Sweeper)
{
this.#logger.info(`Registering sweeper ${name}`);
if (!sweeper.name.includes('Bound'))
this.#logger.warn(`Sweeper ${name} is not bound, may cause issues if 'this' is referenced`);
this.#sweepers.set(name, sweeper);
}
async #runSweepers ()
{
const sweepers = this.#sweepers.entries();
for (const [ name, sweeper ] of sweepers)
{
this.#logger.info(`Running sweeper ${name}`);
await sweeper();
}
}
// Middleware
#attachMisc (req: Request, _res: Response, next: NextFunction) #attachMisc (req: Request, _res: Response, next: NextFunction)
{ {
req.remoteAddress = req.get('X-Forwarded-For') || req.socket.remoteAddress as string; req.remoteAddress = req.get('X-Forwarded-For') || req.socket.remoteAddress as string;
@ -310,6 +343,7 @@ class Server extends EventEmitter
return void res.status(503).send('Server not ready'); return void res.status(503).send('Server not ready');
next(); next();
} }
// END Middleware
async shutdown () async shutdown ()
{ {
@ -319,6 +353,7 @@ class Server extends EventEmitter
process.send({ _shutdown: true }); process.send({ _shutdown: true });
this.#_ready = false; this.#_ready = false;
clearInterval(this.#sweeperInterval);
// Close http server first and allow it to finish serving requests // Close http server first and allow it to finish serving requests
if (this.#server) if (this.#server)
{ {