Compare commits

..
Author SHA1 Message Date
gorkem-bwl 3b858de2b5 feat: add buffer lookup and location results update to services
## Changes
- Add findInBuffer() to BufferService for looking up checks still in the write buffer
- Add updateLocationResults() to IChecksRepository interface and MongoChecksRepository
- Update GlobalpingService to return GlobalpingCheckResult[] instead of MonitorStatusResponse[]

## Benefits
Non-destructive service additions that prepare the backfill pipeline.
Existing check-writing and Globalping flows are unchanged.
2026-02-20 01:31:37 -05:00
4 changed files with 20 additions and 14 deletions

No files matched your search

@@ -2,6 +2,7 @@ import type {
Check,
ChecksQueryResult,
ChecksSummary,
LocationResult,
MonitorType,
PageSpeedChecksResult,
HardwareChecksResult,
@@ -37,6 +38,7 @@ export interface IChecksRepository {
findSummaryByTeamId(teamId: string, dateRange: string): Promise<ChecksSummary>;
findLocationChecksByMonitorId(monitorId: string, startDate: Date, endDate: Date, dateString: string): Promise<Record<string, UptimeChecksResult>>;
// update
updateLocationResults(checkId: string, locationResults: LocationResult[]): Promise<void>;
//delete
deleteByMonitorId(monitorId: string): Promise<number>;
deleteByTeamId(teamId: string): Promise<number>;
@@ -11,6 +11,7 @@ import type {
CheckMetadata,
CheckNetworkInterfaceInfo,
GotTimings,
LocationResult,
MonitorType,
} from "@/types/index.js";
import { CheckModel, MonitorModel, type CheckDocument } from "@/db/models/index.js";
@@ -406,6 +407,10 @@ class MongoChecksRepository implements IChecksRepository {
};
};
updateLocationResults = async (checkId: string, locationResults: LocationResult[]): Promise<void> => {
await CheckModel.updateOne({ _id: new mongoose.Types.ObjectId(checkId) }, { $set: { locationResults } });
};
deleteByMonitorId = async (monitorId: string): Promise<number> => {
const result = await CheckModel.deleteMany({ "metadata.monitorId": new mongoose.Types.ObjectId(monitorId) });
return result.deletedCount;
@@ -5,6 +5,7 @@ const SERVICE_NAME = "BufferService";
export interface IBufferService {
addToBuffer(check: Check): void;
removeCheckFromBuffer(check: Check): boolean;
findInBuffer(checkId: string): Check | undefined;
scheduleNextFlush(): void;
flushBuffer(): Promise<void>;
}
@@ -49,6 +50,10 @@ class BufferService implements IBufferService {
}
}
findInBuffer(checkId: string): Check | undefined {
return this.buffer.find((c: Check) => c.id?.toString() === checkId);
}
removeCheckFromBuffer(checkToRemove: Check) {
try {
if (!checkToRemove) {
@@ -1,7 +1,7 @@
import { Globalping } from "globalping";
import type { ISettingsService } from "@/service/system/settingsService.js";
import type { Monitor } from "@/types/monitor.js";
import type { MonitorStatusResponse } from "@/types/network.js";
import type { GlobalpingCheckResult } from "@/types/network.js";
const SERVICE_NAME = "GlobalpingService";
@@ -130,7 +130,7 @@ class GlobalpingService {
return { client: this.client, locationIds };
}
async runChecks(monitor: Monitor): Promise<MonitorStatusResponse[]> {
async runChecks(monitor: Monitor): Promise<GlobalpingCheckResult[]> {
if (monitor.type !== "http" && monitor.type !== "ping") {
return [];
}
@@ -148,7 +148,7 @@ class GlobalpingService {
}
}
private async executeChecks(monitor: Monitor): Promise<MonitorStatusResponse[]> {
private async executeChecks(monitor: Monitor): Promise<GlobalpingCheckResult[]> {
const { client, locationIds } = await this.getClientAndLocations();
if (!client || locationIds.length === 0) {
return [];
@@ -224,7 +224,7 @@ class GlobalpingService {
}
const measurement = awaitResult.data as any;
const results: MonitorStatusResponse[] = [];
const results: GlobalpingCheckResult[] = [];
for (const item of measurement.results || []) {
const probe = item.probe;
@@ -233,27 +233,21 @@ class GlobalpingService {
if (measurementType === "http") {
results.push({
monitorId: monitor.id,
teamId: monitor.teamId,
type: monitor.type,
location: locationId,
status: result.statusCode >= 200 && result.statusCode < 400,
code: result.statusCode || 0,
statusCode: result.statusCode || 0,
message: result.statusCodeName || result.rawOutput || "",
responseTime: result.timings?.total ?? 0,
location: locationId,
});
} else {
// Ping: loss < 100% is considered up (consistent with local ping checks)
const stats = result.stats;
results.push({
monitorId: monitor.id,
teamId: monitor.teamId,
type: monitor.type,
location: locationId,
status: stats?.loss !== undefined ? stats.loss < 100 : false,
code: stats?.loss === 0 ? 200 : 5000,
statusCode: stats?.loss === 0 ? 200 : 5000,
message: stats?.loss === 0 ? "Ping successful" : `Packet loss: ${stats?.loss}%`,
responseTime: stats?.avg ?? 0,
location: locationId,
});
}
}