Skip to content

Commit bdcbd4c

Browse files
authored
fix(globalping): retry creating the measurement on status 500 (louislam#7056)
1 parent 174c63d commit bdcbd4c

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed

server/monitor-types/globalping.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class GlobalpingMonitorType extends MonitorType {
9090
log.debug("monitor", `Globalping create measurement: ${JSON.stringify(opts)}`);
9191
let res = await client.createMeasurement(opts);
9292

93+
// Retry if the server returns a 500 error
94+
if (!res.ok && Globalping.isHttpStatus(500, res)) {
95+
res = await client.createMeasurement(opts);
96+
}
97+
9398
if (!res.ok) {
9499
if (Globalping.isHttpStatus(429, res)) {
95100
throw new Error(`Failed to create measurement: ${this.formatTooManyRequestsError(hasAPIToken)}`);
@@ -187,6 +192,11 @@ class GlobalpingMonitorType extends MonitorType {
187192
log.debug("monitor", `Globalping create measurement: ${JSON.stringify(opts)}`);
188193
let res = await client.createMeasurement(opts);
189194

195+
// Retry if the server returns a 500 error
196+
if (!res.ok && Globalping.isHttpStatus(500, res)) {
197+
res = await client.createMeasurement(opts);
198+
}
199+
190200
if (!res.ok) {
191201
if (Globalping.isHttpStatus(429, res)) {
192202
throw new Error(`Failed to create measurement: ${this.formatTooManyRequestsError(hasAPIToken)}`);
@@ -275,7 +285,14 @@ class GlobalpingMonitorType extends MonitorType {
275285

276286
log.debug("monitor", `Globalping create measurement: ${JSON.stringify(opts)}`);
277287
let res = await client.createMeasurement(opts);
288+
278289
log.debug("monitor", `Globalping ${JSON.stringify(res)}`);
290+
291+
// Retry if the server returns a 500 error
292+
if (!res.ok && Globalping.isHttpStatus(500, res)) {
293+
res = await client.createMeasurement(opts);
294+
}
295+
279296
if (!res.ok) {
280297
if (Globalping.isHttpStatus(429, res)) {
281298
throw new Error(`Failed to create measurement: ${this.formatTooManyRequestsError(hasAPIToken)}`);

test/backend-test/test-globalping.js

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,63 @@ describe("GlobalpingMonitorType", () => {
165165
return true;
166166
});
167167
});
168+
169+
test("should retry create measurement on status 500", async () => {
170+
const monitorType = new GlobalpingMonitorType("test-agent/1.0");
171+
const mockClient = createGlobalpingClientMock();
172+
const createResponse = createMockResponse({
173+
id: "2g8T7V3OwXG3JV6Y10011zF2v",
174+
});
175+
const measurement = createPingMeasurement();
176+
const awaitResponse = createMockResponse(measurement);
177+
178+
mockClient.createMeasurement.mock.mockImplementationOnce(() => ({
179+
ok: false,
180+
response: {
181+
status: 500,
182+
},
183+
}));
184+
mockClient.createMeasurement.mock.mockImplementation(() => createResponse);
185+
mockClient.awaitMeasurement.mock.mockImplementation(() => awaitResponse);
186+
187+
const monitor = {
188+
hostname: "example.com",
189+
location: "North America",
190+
ping_count: 3,
191+
protocol: "ICMP",
192+
ipFamily: "ipv4",
193+
};
194+
195+
const heartbeat = {
196+
status: PENDING,
197+
msg: "",
198+
ping: 0,
199+
};
200+
201+
await monitorType.ping(mockClient, monitor, heartbeat, true);
202+
203+
const expectedCreateMeasurement = {
204+
type: "ping",
205+
target: "example.com",
206+
inProgressUpdates: false,
207+
limit: 1,
208+
locations: [{ magic: "North America" }],
209+
measurementOptions: {
210+
packets: 3,
211+
protocol: "ICMP",
212+
ipVersion: 4,
213+
},
214+
};
215+
assert.strictEqual(mockClient.createMeasurement.mock.calls.length, 2);
216+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[0].arguments[0], expectedCreateMeasurement);
217+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[1].arguments[0], expectedCreateMeasurement);
218+
219+
assert.deepStrictEqual(heartbeat, {
220+
status: UP,
221+
msg: "Ashburn (VA), US, NA, Amazon.com (AS14618), (aws-us-east-1) : OK",
222+
ping: 2.169,
223+
});
224+
});
168225
});
169226

170227
describe("http", () => {
@@ -579,6 +636,80 @@ describe("GlobalpingMonitorType", () => {
579636
return true;
580637
});
581638
});
639+
640+
test("should retry create measurement on status 500", async () => {
641+
const monitorType = new GlobalpingMonitorType("test-agent/1.0");
642+
const mockClient = createGlobalpingClientMock();
643+
const createResponse = createMockResponse({
644+
id: "2g8T7V3OwXG3JV6Y10011zF2v",
645+
});
646+
const measurement = createHttpMeasurement();
647+
const awaitResponse = createMockResponse(measurement);
648+
649+
mockClient.createMeasurement.mock.mockImplementationOnce(() => ({
650+
ok: false,
651+
response: {
652+
status: 500,
653+
},
654+
}));
655+
mockClient.createMeasurement.mock.mockImplementation(() => createResponse);
656+
mockClient.awaitMeasurement.mock.mockImplementation(() => awaitResponse);
657+
658+
const monitor = {
659+
url: "https://example.com:444/api/test?test=1",
660+
location: "North America",
661+
method: "GET",
662+
accepted_statuscodes_json: JSON.stringify(["200-299", "300-399"]),
663+
headers: '{"Test-Header": "Test-Value"}',
664+
ipFamily: "ipv4",
665+
dns_resolve_server: "8.8.8.8",
666+
auth_method: "basic",
667+
basic_auth_user: "username",
668+
basic_auth_pass: "password",
669+
};
670+
671+
const heartbeat = {
672+
status: PENDING,
673+
msg: "",
674+
ping: 0,
675+
};
676+
677+
await monitorType.http(mockClient, monitor, heartbeat, true);
678+
679+
const expectedToken = encodeBase64(monitor.basic_auth_user, monitor.basic_auth_pass);
680+
const expectedCreateMeasurement = {
681+
type: "http",
682+
target: "example.com",
683+
inProgressUpdates: false,
684+
limit: 1,
685+
locations: [{ magic: "North America" }],
686+
measurementOptions: {
687+
request: {
688+
host: "example.com",
689+
path: "/api/test",
690+
query: "test=1",
691+
method: "GET",
692+
headers: {
693+
"Test-Header": "Test-Value",
694+
Authorization: `Basic ${expectedToken}`,
695+
},
696+
},
697+
port: 444,
698+
protocol: "HTTPS",
699+
ipVersion: 4,
700+
resolver: "8.8.8.8",
701+
},
702+
};
703+
assert.strictEqual(mockClient.createMeasurement.mock.calls.length, 2);
704+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[0].arguments[0], expectedCreateMeasurement);
705+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[1].arguments[0], expectedCreateMeasurement);
706+
707+
assert.deepStrictEqual(heartbeat, {
708+
status: UP,
709+
msg: "New York (NY), US, NA, MASSIVEGRID (AS49683) : OK",
710+
ping: 1440,
711+
});
712+
});
582713
});
583714

584715
describe("dns", () => {
@@ -844,6 +975,73 @@ describe("GlobalpingMonitorType", () => {
844975
["93.184.216.34", "1"],
845976
]);
846977
});
978+
979+
test("should retry create measurement on status 500", async () => {
980+
const monitorType = new GlobalpingMonitorType("test-agent/1.0");
981+
const mockClient = createGlobalpingClientMock();
982+
const createResponse = createMockResponse({
983+
id: "2g8T7V3OwXG3JV6Y10011zF2v",
984+
});
985+
const measurement = createDnsMeasurement();
986+
const awaitResponse = createMockResponse(measurement);
987+
988+
mockClient.createMeasurement.mock.mockImplementationOnce(() => ({
989+
ok: false,
990+
response: {
991+
status: 500,
992+
},
993+
}));
994+
mockClient.createMeasurement.mock.mockImplementation(() => createMockResponse(createResponse));
995+
mockClient.awaitMeasurement.mock.mockImplementation(() => awaitResponse);
996+
997+
const redbeanMock = createRedbeanMock();
998+
redbeanMock.exec.mock.mockImplementation(() => Promise.resolve());
999+
1000+
const monitor = {
1001+
id: "1",
1002+
hostname: "example.com",
1003+
location: "us-east-1",
1004+
dns_resolve_type: "A",
1005+
port: 53,
1006+
protocol: "udp",
1007+
};
1008+
1009+
const heartbeat = {
1010+
status: PENDING,
1011+
msg: "",
1012+
ping: null,
1013+
};
1014+
1015+
await monitorType.dns(mockClient, monitor, heartbeat, false, redbeanMock);
1016+
1017+
const expectedCreateMeasurement = {
1018+
type: "dns",
1019+
target: "example.com",
1020+
inProgressUpdates: false,
1021+
limit: 1,
1022+
locations: [{ magic: "us-east-1" }],
1023+
measurementOptions: {
1024+
query: { type: "A" },
1025+
port: 53,
1026+
protocol: "udp",
1027+
},
1028+
};
1029+
assert.strictEqual(mockClient.createMeasurement.mock.calls.length, 2);
1030+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[0].arguments[0], expectedCreateMeasurement);
1031+
assert.deepStrictEqual(mockClient.createMeasurement.mock.calls[1].arguments[0], expectedCreateMeasurement);
1032+
1033+
assert.deepStrictEqual(heartbeat, {
1034+
status: UP,
1035+
msg: "New York (NY), US, NA, MASSIVEGRID (AS49683) : 93.184.216.34",
1036+
ping: 25,
1037+
});
1038+
1039+
assert.strictEqual(redbeanMock.exec.mock.calls.length, 1);
1040+
assert.deepStrictEqual(redbeanMock.exec.mock.calls[0].arguments, [
1041+
"UPDATE `monitor` SET dns_last_result = ? WHERE id = ? ",
1042+
["93.184.216.34", "1"],
1043+
]);
1044+
});
8471045
});
8481046

8491047
describe("helper methods", () => {

0 commit comments

Comments
 (0)