Browse Source

refactor: move JobQueue stats to a dedicated JobStatistics singleton-like class

Kristian Vos 2 years ago
parent
commit
a68a770b8d
4 changed files with 98 additions and 74 deletions
  1. 9 71
      backend/src/JobQueue.ts
  2. 80 0
      backend/src/JobStatistics.ts
  3. 5 3
      backend/src/ModuleManager.ts
  4. 4 0
      backend/src/main.ts

+ 9 - 71
backend/src/JobQueue.ts

@@ -1,6 +1,7 @@
 import BaseModule from "./BaseModule";
 import Job from "./Job";
 import JobContext from "./JobContext";
+import JobStatistics from "./JobStatistics";
 import LogBook from "./LogBook";
 import ModuleManager from "./ModuleManager";
 import { JobOptions } from "./types/JobOptions";
@@ -18,23 +19,14 @@ export default class JobQueue {
 
 	private active: Job[];
 
-	private stats: Record<
-		string,
-		{
-			successful: number;
-			failed: number;
-			total: number;
-			added: number;
-			averageTime: number;
-		}
-	>;
-
 	private processLock: boolean;
 
 	private moduleManager: ModuleManager;
 
 	private logBook: LogBook;
 
+	private jobStatistics: JobStatistics;
+
 	/**
 	 * Job Queue
 	 */
@@ -44,11 +36,11 @@ export default class JobQueue {
 		this.jobs = [];
 		this.queue = [];
 		this.active = [];
-		this.stats = {};
 		this.processLock = false;
 		this.moduleManager =
 			moduleManager ?? ModuleManager.getPrimaryInstance();
 		this.logBook = LogBook.getPrimaryInstance();
+		this.jobStatistics = JobStatistics.getPrimaryInstance();
 	}
 
 	/**
@@ -57,7 +49,7 @@ export default class JobQueue {
 	 * @param job - Job
 	 */
 	public add(job: Job, runDirectly: boolean) {
-		this.updateStats(job.getName(), "added");
+		this.jobStatistics.updateStats(job.getName(), "added");
 		this.jobs.push(job);
 		if (runDirectly) {
 			this.executeJob(job);
@@ -202,14 +194,14 @@ export default class JobQueue {
 
 		job.execute()
 			.then(() => {
-				this.updateStats(job.getName(), "successful");
+				this.jobStatistics.updateStats(job.getName(), "successful");
 			})
 			.catch(() => {
-				this.updateStats(job.getName(), "failed");
+				this.jobStatistics.updateStats(job.getName(), "failed");
 			})
 			.finally(() => {
-				this.updateStats(job.getName(), "total");
-				this.updateStats(
+				this.jobStatistics.updateStats(job.getName(), "total");
+				this.jobStatistics.updateStats(
 					job.getName(),
 					"averageTime",
 					Date.now() - startTime
@@ -284,33 +276,6 @@ export default class JobQueue {
 		};
 	}
 
-	/**
-	 * getStats - Get statistics of job queue
-	 *
-	 * @returns Job queue statistics
-	 */
-	public getStats() {
-		return {
-			...this.stats,
-			total: Object.values(this.stats).reduce(
-				(a, b) => ({
-					successful: a.successful + b.successful,
-					failed: a.failed + b.failed,
-					total: a.total + b.total,
-					added: a.added + b.added,
-					averageTime: -1
-				}),
-				{
-					successful: 0,
-					failed: 0,
-					total: 0,
-					added: 0,
-					averageTime: -1
-				}
-			)
-		};
-	}
-
 	/**
 	 * getQueueStatus - Get statistics of queued or active jobs
 	 *
@@ -345,31 +310,4 @@ export default class JobQueue {
 	public getJobs() {
 		return this.jobs;
 	}
-
-	/**
-	 * updateStats - Update job statistics
-	 *
-	 * @param jobName - Job name
-	 * @param type - Stats type
-	 * @param duration - Duration of job, for average time stats
-	 */
-	private updateStats(
-		jobName: string,
-		type: "successful" | "failed" | "total" | "added" | "averageTime",
-		duration?: number
-	) {
-		if (!this.stats[jobName])
-			this.stats[jobName] = {
-				successful: 0,
-				failed: 0,
-				total: 0,
-				added: 0,
-				averageTime: 0
-			};
-		if (type === "averageTime" && duration)
-			this.stats[jobName].averageTime +=
-				(duration - this.stats[jobName].averageTime) /
-				this.stats[jobName].total;
-		else this.stats[jobName][type] += 1;
-	}
 }

+ 80 - 0
backend/src/JobStatistics.ts

@@ -0,0 +1,80 @@
+export default class JobStatistics {
+	static primaryInstance: JobStatistics;
+
+	private stats: Record<
+		string,
+		{
+			successful: number;
+			failed: number;
+			total: number;
+			added: number;
+			averageTime: number;
+		}
+	>;
+
+	public constructor() {
+		this.stats = {};
+	}
+
+	/**
+	 * getStats - Get statistics of job queue
+	 *
+	 * @returns Job queue statistics
+	 */
+	public getStats() {
+		return {
+			...this.stats,
+			total: Object.values(this.stats).reduce(
+				(a, b) => ({
+					successful: a.successful + b.successful,
+					failed: a.failed + b.failed,
+					total: a.total + b.total,
+					added: a.added + b.added,
+					averageTime: -1
+				}),
+				{
+					successful: 0,
+					failed: 0,
+					total: 0,
+					added: 0,
+					averageTime: -1
+				}
+			)
+		};
+	}
+
+	/**
+	 * updateStats - Update job statistics
+	 *
+	 * @param jobName - Job name
+	 * @param type - Stats type
+	 * @param duration - Duration of job, for average time stats
+	 */
+	public updateStats(
+		jobName: string,
+		type: "successful" | "failed" | "total" | "added" | "averageTime",
+		duration?: number
+	) {
+		if (!this.stats[jobName])
+			this.stats[jobName] = {
+				successful: 0,
+				failed: 0,
+				total: 0,
+				added: 0,
+				averageTime: 0
+			};
+		if (type === "averageTime" && duration)
+			this.stats[jobName].averageTime +=
+				(duration - this.stats[jobName].averageTime) /
+				this.stats[jobName].total;
+		else this.stats[jobName][type] += 1;
+	}
+
+	static getPrimaryInstance(): JobStatistics {
+		return this.primaryInstance;
+	}
+
+	static setPrimaryInstance(jobStatistics: JobStatistics) {
+		this.primaryInstance = jobStatistics;
+	}
+}

+ 5 - 3
backend/src/ModuleManager.ts

@@ -1,7 +1,6 @@
 import BaseModule from "./BaseModule";
-import Job from "./Job";
-import JobContext from "./JobContext";
 import JobQueue from "./JobQueue";
+import JobStatistics from "./JobStatistics";
 import { JobOptions } from "./types/JobOptions";
 import { Jobs, Modules, ModuleStatus, ModuleClass } from "./types/Modules";
 
@@ -12,11 +11,14 @@ export default class ModuleManager {
 
 	private jobQueue: JobQueue;
 
+	private jobStatistics: JobStatistics;
+
 	/**
 	 * Module Manager
 	 */
 	public constructor() {
 		this.jobQueue = new JobQueue(this);
+		this.jobStatistics = JobStatistics.getPrimaryInstance();
 	}
 
 	/**
@@ -38,7 +40,7 @@ export default class ModuleManager {
 	 * @returns Job queue statistics
 	 */
 	public getJobsStats() {
-		return this.jobQueue.getStats();
+		return this.jobStatistics.getStats();
 	}
 
 	/**

+ 4 - 0
backend/src/main.ts

@@ -3,6 +3,7 @@ import { ObjectId } from "mongodb";
 import ModuleManager from "./ModuleManager";
 import LogBook from "./LogBook";
 import Job from "./Job";
+import JobStatistics from "./JobStatistics";
 
 const logBook = new LogBook();
 LogBook.setPrimaryInstance(logBook);
@@ -27,6 +28,9 @@ process.on("uncaughtException", err => {
 	});
 });
 
+const jobStatistics = new JobStatistics();
+JobStatistics.setPrimaryInstance(jobStatistics);
+
 const moduleManager = new ModuleManager();
 ModuleManager.setPrimaryInstance(moduleManager);
 moduleManager.startup();