From 14f68d58f712c99ecd549d6d3437ef2b32e505b1 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 17 Jun 2024 10:47:36 -0700 Subject: [PATCH 1/3] Implemented network service --- Server/service/jobQueue.js | 31 +++++-------- Server/service/networkService.js | 79 ++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 Server/service/networkService.js diff --git a/Server/service/jobQueue.js b/Server/service/jobQueue.js index 43983bc48..511f01e9a 100644 --- a/Server/service/jobQueue.js +++ b/Server/service/jobQueue.js @@ -7,9 +7,8 @@ const connection = { const JOBS_PER_WORKER = 5; const logger = require("../utils/logger"); const { errorMessages, successMessages } = require("../utils/messages"); +const NetworkService = require("./networkService"); const SERVICE_NAME = "JobQueue"; -const axios = require("axios"); -const ping = require("ping"); class JobQueue { /** @@ -23,6 +22,7 @@ class JobQueue { }); this.workers = []; this.db = null; + this.networkService = null; } /** @@ -36,6 +36,7 @@ class JobQueue { const queue = new JobQueue(); try { queue.db = db; + queue.networkService = new NetworkService(db); const monitors = await db.getAllMonitors(); for (const monitor of monitors) { await queue.addJob(monitor.id, monitor); @@ -57,24 +58,14 @@ class JobQueue { const worker = new Worker( QUEUE_NAME, async (job) => { - // TODO Extract to service - if (job.data.type === "ping") { - const response = await ping.promise.probe(job.data.url); - // TODO insert checks into DB - if (response.alive === true) { - console.log(`${job.data.url} is alive`); - } else { - console.log(`${job.data.url} is dead`); - } - } else if (job.data.type === "http") { - const response = await axios.get(job.data.url); - // TODO create a check object and save it to the db - if (response.status >= 200 && response.status < 300) { - // TODO insert checks into DB - console.log(`${job.data.url} is alive`); - } else { - console.log(`${job.data.url} is dead`); - } + try { + await this.networkService.getStatus(job); + } catch (error) { + logger.error(`Error processing job ${job.id}: ${error.message}`, { + service: SERVICE_NAME, + jobId: job.id, + error: error, + }); } }, { diff --git a/Server/service/networkService.js b/Server/service/networkService.js new file mode 100644 index 000000000..ed2006917 --- /dev/null +++ b/Server/service/networkService.js @@ -0,0 +1,79 @@ +const axios = require("axios"); +const ping = require("ping"); +const logger = require("../utils/logger"); + +class NetworkService { + constructor(db) { + this.db = db; + this.TYPE_PING = "ping"; + this.TYPE_HTTP = "http"; + this.SERVICE_NAME = "NetworkService"; + } + + async handlePing(job) { + try { + const response = await ping.promise.probe(job.data.url); + const isAlive = response.alive; + await this.logAndStoreCheck(job, isAlive); + return isAlive; + } catch (error) { + await this.logAndStoreCheck(job, false, error); + return false; + } + } + + async handleHttp(job) { + try { + const response = await axios.get(job.data.url); + const isAlive = response.status >= 200 && response.status < 300; + await this.logAndStoreCheck(job, isAlive); + return isAlive; + } catch (error) { + await this.logAndStoreCheck(job, false, error); + return false; + } + } + + async getStatus(job) { + try { + switch (job.data.type) { + case this.TYPE_PING: + return await this.handlePing(job); + case this.TYPE_HTTP: + return await this.handleHttp(job); + default: + console.error(`Unsupported type: ${job.data.type}`, { + service: this.SERVICE_NAME, + timestamp: new Date().toISOString(), + }); + return false; + } + } catch (error) { + throw error; + } + } + + async logAndStoreCheck(job, isAlive, error = null) { + const status = isAlive ? "alive" : "dead"; + if (error) { + logger.error(`Error processing job ${job.id}: ${error.message}`, { + service: this.SERVICE_NAME, + jobId: job.id, + error: error, + }); + return; + } + + if (isAlive) { + console.log(`Job ${job.data.url} is alive`); + return; + } + + if (!isAlive) { + console.log(`Job ${job.data.url} is dead`); + return; + } + } +} + +module.exports = NetworkService; From a0ca205d6a37c7436a0a96b4b8110f3106e52b65 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 17 Jun 2024 11:05:22 -0700 Subject: [PATCH 2/3] Added response time --- Server/service/networkService.js | 50 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/Server/service/networkService.js b/Server/service/networkService.js index ed2006917..12ff8a99b 100644 --- a/Server/service/networkService.js +++ b/Server/service/networkService.js @@ -11,49 +11,55 @@ class NetworkService { } async handlePing(job) { + const startTime = Date.now(); try { const response = await ping.promise.probe(job.data.url); const isAlive = response.alive; - await this.logAndStoreCheck(job, isAlive); + const endTime = Date.now(); + const responseTime = endTime - startTime; + await this.logAndStoreCheck(job, isAlive, responseTime); return isAlive; } catch (error) { - await this.logAndStoreCheck(job, false, error); + const endTime = Date.now(); + const responseTime = endTime - startTime; + await this.logAndStoreCheck(job, false, responseTime, error); return false; } } async handleHttp(job) { try { + const startTime = Date.now(); const response = await axios.get(job.data.url); const isAlive = response.status >= 200 && response.status < 300; - await this.logAndStoreCheck(job, isAlive); + const endTime = Date.now(); + const responseTime = endTime - startTime; + await this.logAndStoreCheck(job, isAlive, responseTime); return isAlive; } catch (error) { - await this.logAndStoreCheck(job, false, error); + const endTime = Date.now(); + const responseTime = endTime - startTime; + await this.logAndStoreCheck(job, false, responseTime, error); return false; } } async getStatus(job) { - try { - switch (job.data.type) { - case this.TYPE_PING: - return await this.handlePing(job); - case this.TYPE_HTTP: - return await this.handleHttp(job); - default: - console.error(`Unsupported type: ${job.data.type}`, { - service: this.SERVICE_NAME, - timestamp: new Date().toISOString(), - }); - return false; - } - } catch (error) { - throw error; + switch (job.data.type) { + case this.TYPE_PING: + return await this.handlePing(job); + case this.TYPE_HTTP: + return await this.handleHttp(job); + default: + console.error(`Unsupported type: ${job.data.type}`, { + service: this.SERVICE_NAME, + timestamp: new Date().toISOString(), + }); + return false; } } - async logAndStoreCheck(job, isAlive, error = null) { + async logAndStoreCheck(job, isAlive, responseTime, error = null) { const status = isAlive ? "alive" : "dead"; if (error) { logger.error(`Error processing job ${job.id}: ${error.message}`, { @@ -65,7 +71,9 @@ class NetworkService { } if (isAlive) { - console.log(`Job ${job.data.url} is alive`); + console.log( + `Job ${job.data.url} is alive, response time: ${responseTime}ms` + ); return; } From 0b52a5bdc7e7a9469d422f50c07021f14bcec0c7 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 17 Jun 2024 11:33:55 -0700 Subject: [PATCH 3/3] Fixed error handling, refactored response time measurement --- Server/service/networkService.js | 54 ++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/Server/service/networkService.js b/Server/service/networkService.js index 12ff8a99b..1e1da69c2 100644 --- a/Server/service/networkService.js +++ b/Server/service/networkService.js @@ -10,36 +10,50 @@ class NetworkService { this.SERVICE_NAME = "NetworkService"; } - async handlePing(job) { + async measureResponseTime(operation) { const startTime = Date.now(); try { - const response = await ping.promise.probe(job.data.url); - const isAlive = response.alive; + const response = await operation(); const endTime = Date.now(); - const responseTime = endTime - startTime; + return { responseTime: endTime - startTime, response }; + } catch (error) { + throw error; + } + } + + async handlePing(job) { + const operation = async () => { + const response = await ping.promise.probe(job.data.url); + return response; + }; + + try { + const { responseTime, response } = await this.measureResponseTime( + operation + ); + const isAlive = response.alive; await this.logAndStoreCheck(job, isAlive, responseTime); return isAlive; } catch (error) { - const endTime = Date.now(); - const responseTime = endTime - startTime; - await this.logAndStoreCheck(job, false, responseTime, error); + await this.logAndStoreCheck(job, false, 0, error); return false; } } async handleHttp(job) { - try { - const startTime = Date.now(); + const operation = async () => { const response = await axios.get(job.data.url); + return response; + }; + try { + const { responseTime, response } = await this.measureResponseTime( + operation + ); const isAlive = response.status >= 200 && response.status < 300; - const endTime = Date.now(); - const responseTime = endTime - startTime; await this.logAndStoreCheck(job, isAlive, responseTime); return isAlive; } catch (error) { - const endTime = Date.now(); - const responseTime = endTime - startTime; - await this.logAndStoreCheck(job, false, responseTime, error); + await this.logAndStoreCheck(job, false, 0, error); return false; } } @@ -62,11 +76,7 @@ class NetworkService { async logAndStoreCheck(job, isAlive, responseTime, error = null) { const status = isAlive ? "alive" : "dead"; if (error) { - logger.error(`Error processing job ${job.id}: ${error.message}`, { - service: this.SERVICE_NAME, - jobId: job.id, - error: error, - }); + console.log(`Job ${job.data.url} is dead`); return; } @@ -77,10 +87,8 @@ class NetworkService { return; } - if (!isAlive) { - console.log(`Job ${job.data.url} is dead`); - return; - } + console.log(`Job ${job.data.url} is dead`); + return; } }