Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4dfa8d7

Browse files
author
Guy Bedford
authoredMay 24, 2024
feat: support default timeout configurations for dynamic backends (#792)
1 parent b38dd94 commit 4dfa8d7

File tree

9 files changed

+161
-28
lines changed

9 files changed

+161
-28
lines changed
 

‎integration-tests/js-compute/fixtures/app/src/dynamic-backend.js

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,31 @@ import { isRunningLocally, routes } from "./routes.js";
88
/// The backend name is already in use.
99

1010
routes.set("/backend/timeout", async () => {
11-
if (isRunningLocally()) {
12-
return pass('ok')
13-
}
14-
allowDynamicBackends(true);
15-
let backend = new Backend(
16-
{
17-
name: 'httpme1',
18-
target: 'http-me.glitch.me',
19-
hostOverride: "http-me.glitch.me",
20-
useSSL: true,
21-
dontPool: true,
22-
betweenBytesTimeout: 1_000,
23-
connectTimeout: 1_000,
24-
firstByteTimeout: 1_000
25-
}
26-
);
27-
console.time(`fetch('https://http-me.glitch.me/test?wait=5000'`)
28-
let error = await assertRejects(() => fetch('https://http-me.glitch.me/test?wait=5000', {
29-
backend,
30-
cacheOverride: new CacheOverride("pass"),
31-
}));
32-
console.timeEnd(`fetch('https://http-me.glitch.me/test?wait=5000'`)
33-
if (error) { return error }
11+
if (isRunningLocally()) {
3412
return pass('ok')
35-
});
36-
13+
}
14+
allowDynamicBackends(true);
15+
let backend = new Backend(
16+
{
17+
name: 'httpme1',
18+
target: 'http-me.glitch.me',
19+
hostOverride: "http-me.glitch.me",
20+
useSSL: true,
21+
dontPool: true,
22+
betweenBytesTimeout: 1_000,
23+
connectTimeout: 1_000,
24+
firstByteTimeout: 1_000
25+
}
26+
);
27+
console.time(`fetch('https://http-me.glitch.me/test?wait=5000'`)
28+
let error = await assertRejects(() => fetch('https://http-me.glitch.me/test?wait=5000', {
29+
backend,
30+
cacheOverride: new CacheOverride("pass"),
31+
}));
32+
console.timeEnd(`fetch('https://http-me.glitch.me/test?wait=5000'`)
33+
if (error) { return error }
34+
return pass('ok')
35+
});
3736

3837
// implicit dynamic backend
3938
{
@@ -59,6 +58,21 @@ routes.set("/backend/timeout", async () => {
5958
if (error) { return error }
6059
return pass('ok')
6160
});
61+
routes.set("/implicit-dynamic-backend/default-timeouts", async () => {
62+
if (isRunningLocally()) {
63+
return pass('ok');
64+
}
65+
allowDynamicBackends({
66+
betweenBytesTimeout: 1_000,
67+
connectTimeout: 1_000,
68+
firstByteTimeout: 1_000
69+
});
70+
console.time(`fetch('https://http-me.glitch.me/test?wait=5000'`)
71+
let error = await assertRejects(() => fetch('https://http-me.glitch.me/test?wait=5000'));
72+
console.timeEnd(`fetch('https://http-me.glitch.me/test?wait=5000'`)
73+
if (error) { return error }
74+
return pass('ok')
75+
});
6276
}
6377

6478
// explicit dynamic backend

‎runtime/fastly/builtins/backend.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "fastly.h"
2626

2727
using builtins::BuiltinImpl;
28+
using fastly::fastly::Fastly;
2829
using fastly::fastly::FastlyGetErrorMessage;
2930
using fastly::fetch::RequestOrResponse;
3031

@@ -1126,6 +1127,31 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
11261127

11271128
JS::SetReservedSlot(backend, Backend::Slots::DontPool, JS::BooleanValue(false));
11281129

1130+
if (Fastly::defaultDynamicBackendConfig.connect_timeout.has_value()) {
1131+
JS::RootedValue connect_timeout_val(
1132+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.connect_timeout.value()));
1133+
if (!Backend::set_timeout_slot(cx, backend, connect_timeout_val, Backend::Slots::ConnectTimeout,
1134+
"connectTimeout")) {
1135+
return nullptr;
1136+
}
1137+
}
1138+
if (Fastly::defaultDynamicBackendConfig.between_bytes_timeout.has_value()) {
1139+
JS::RootedValue between_bytes_timeout_val(
1140+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.between_bytes_timeout.value()));
1141+
if (!Backend::set_timeout_slot(cx, backend, between_bytes_timeout_val,
1142+
Backend::Slots::BetweenBytesTimeout, "betweenBytesTimeout")) {
1143+
return nullptr;
1144+
}
1145+
}
1146+
if (Fastly::defaultDynamicBackendConfig.first_byte_timeout.has_value()) {
1147+
JS::RootedValue first_byte_timeout_val(
1148+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.first_byte_timeout.value()));
1149+
if (!Backend::set_timeout_slot(cx, backend, first_byte_timeout_val,
1150+
Backend::Slots::FirstByteTimeout, "firstByteTimeout")) {
1151+
return nullptr;
1152+
}
1153+
}
1154+
11291155
auto result = Backend::register_dynamic_backend(cx, backend);
11301156
if (result.isErr()) {
11311157
return nullptr;

‎runtime/fastly/builtins/fastly.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ JS::PersistentRooted<JSObject *> Fastly::env;
4343
JS::PersistentRooted<JSObject *> Fastly::baseURL;
4444
JS::PersistentRooted<JSString *> Fastly::defaultBackend;
4545
bool Fastly::allowDynamicBackends = false;
46+
host_api::BackendConfig Fastly::defaultDynamicBackendConfig;
4647

4748
bool Fastly::dump(JSContext *cx, unsigned argc, JS::Value *vp) {
4849
JS::CallArgs args = CallArgsFromVp(argc, vp);
@@ -307,7 +308,36 @@ bool Fastly::allowDynamicBackends_get(JSContext *cx, unsigned argc, JS::Value *v
307308

308309
bool Fastly::allowDynamicBackends_set(JSContext *cx, unsigned argc, JS::Value *vp) {
309310
JS::CallArgs args = CallArgsFromVp(argc, vp);
310-
allowDynamicBackends = JS::ToBoolean(args.get(0));
311+
JS::HandleValue set_value = args.get(0);
312+
if (set_value.isObject()) {
313+
allowDynamicBackends = true;
314+
RootedObject options_value(cx, &set_value.toObject());
315+
316+
RootedValue connect_timeout(cx);
317+
if (!JS_GetProperty(cx, options_value, "connectTimeout", &connect_timeout)) {
318+
return false;
319+
}
320+
RootedValue between_bytes_timeout(cx);
321+
if (!JS_GetProperty(cx, options_value, "betweenBytesTimeout", &between_bytes_timeout)) {
322+
return false;
323+
}
324+
RootedValue first_byte_timeout(cx);
325+
if (!JS_GetProperty(cx, options_value, "firstByteTimeout", &first_byte_timeout)) {
326+
return false;
327+
}
328+
329+
if (connect_timeout.isNumber()) {
330+
defaultDynamicBackendConfig.connect_timeout = connect_timeout.toNumber();
331+
}
332+
if (between_bytes_timeout.isNumber()) {
333+
defaultDynamicBackendConfig.between_bytes_timeout = between_bytes_timeout.toNumber();
334+
}
335+
if (first_byte_timeout.isNumber()) {
336+
defaultDynamicBackendConfig.first_byte_timeout = first_byte_timeout.toNumber();
337+
}
338+
} else {
339+
allowDynamicBackends = JS::ToBoolean(set_value);
340+
}
311341
args.rval().setUndefined();
312342
return true;
313343
}

‎runtime/fastly/builtins/fastly.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Fastly : public builtins::BuiltinNoConstructor<Fastly> {
4141
static JS::PersistentRooted<JSObject *> baseURL;
4242
static JS::PersistentRooted<JSString *> defaultBackend;
4343
static bool allowDynamicBackends;
44+
static host_api::BackendConfig defaultDynamicBackendConfig;
4445

4546
static const JSPropertySpec properties[];
4647

‎runtime/js-compute-runtime/builtins/backend.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "builtins/backend.h"
2121
#include "builtins/request-response.h"
2222
#include "core/encode.h"
23+
#include "fastly.h"
2324
#include "js-compute-builtins.h"
2425
#include "js/Conversions.h"
2526

@@ -1120,6 +1121,31 @@ JSObject *Backend::create(JSContext *cx, JS::HandleObject request) {
11201121

11211122
JS::SetReservedSlot(backend, Backend::Slots::DontPool, JS::BooleanValue(false));
11221123

1124+
if (Fastly::defaultDynamicBackendConfig.connect_timeout.has_value()) {
1125+
JS::RootedValue connect_timeout_val(
1126+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.connect_timeout.value()));
1127+
if (!Backend::set_timeout_slot(cx, backend, connect_timeout_val, Backend::Slots::ConnectTimeout,
1128+
"connectTimeout")) {
1129+
return nullptr;
1130+
}
1131+
}
1132+
if (Fastly::defaultDynamicBackendConfig.between_bytes_timeout.has_value()) {
1133+
JS::RootedValue between_bytes_timeout_val(
1134+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.between_bytes_timeout.value()));
1135+
if (!Backend::set_timeout_slot(cx, backend, between_bytes_timeout_val,
1136+
Backend::Slots::BetweenBytesTimeout, "betweenBytesTimeout")) {
1137+
return nullptr;
1138+
}
1139+
}
1140+
if (Fastly::defaultDynamicBackendConfig.first_byte_timeout.has_value()) {
1141+
JS::RootedValue first_byte_timeout_val(
1142+
cx, JS::NumberValue(Fastly::defaultDynamicBackendConfig.first_byte_timeout.value()));
1143+
if (!Backend::set_timeout_slot(cx, backend, first_byte_timeout_val,
1144+
Backend::Slots::FirstByteTimeout, "firstByteTimeout")) {
1145+
return nullptr;
1146+
}
1147+
}
1148+
11231149
auto result = Backend::register_dynamic_backend(cx, backend);
11241150
if (result.isErr()) {
11251151
return nullptr;

‎runtime/js-compute-runtime/builtins/fastly.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ JS::PersistentRooted<JSObject *> Fastly::env;
2626
JS::PersistentRooted<JSObject *> Fastly::baseURL;
2727
JS::PersistentRooted<JSString *> Fastly::defaultBackend;
2828
bool Fastly::allowDynamicBackends = false;
29+
host_api::BackendConfig Fastly::defaultDynamicBackendConfig;
2930

3031
bool Fastly::dump(JSContext *cx, unsigned argc, JS::Value *vp) {
3132
JS::CallArgs args = CallArgsFromVp(argc, vp);
@@ -258,7 +259,36 @@ bool Fastly::allowDynamicBackends_get(JSContext *cx, unsigned argc, JS::Value *v
258259

259260
bool Fastly::allowDynamicBackends_set(JSContext *cx, unsigned argc, JS::Value *vp) {
260261
JS::CallArgs args = CallArgsFromVp(argc, vp);
261-
allowDynamicBackends = JS::ToBoolean(args.get(0));
262+
JS::HandleValue set_value = args.get(0);
263+
if (set_value.isObject()) {
264+
allowDynamicBackends = true;
265+
JS::RootedObject options_value(cx, &set_value.toObject());
266+
267+
JS::RootedValue connect_timeout(cx);
268+
if (!JS_GetProperty(cx, options_value, "connectTimeout", &connect_timeout)) {
269+
return false;
270+
}
271+
JS::RootedValue between_bytes_timeout(cx);
272+
if (!JS_GetProperty(cx, options_value, "betweenBytesTimeout", &between_bytes_timeout)) {
273+
return false;
274+
}
275+
JS::RootedValue first_byte_timeout(cx);
276+
if (!JS_GetProperty(cx, options_value, "firstByteTimeout", &first_byte_timeout)) {
277+
return false;
278+
}
279+
280+
if (connect_timeout.isNumber()) {
281+
defaultDynamicBackendConfig.connect_timeout = connect_timeout.toNumber();
282+
}
283+
if (between_bytes_timeout.isNumber()) {
284+
defaultDynamicBackendConfig.between_bytes_timeout = between_bytes_timeout.toNumber();
285+
}
286+
if (first_byte_timeout.isNumber()) {
287+
defaultDynamicBackendConfig.first_byte_timeout = first_byte_timeout.toNumber();
288+
}
289+
} else {
290+
allowDynamicBackends = JS::ToBoolean(set_value);
291+
}
262292
args.rval().setUndefined();
263293
return true;
264294
}

‎runtime/js-compute-runtime/builtins/fastly.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class Fastly : public BuiltinNoConstructor<Fastly> {
2020
static JS::PersistentRooted<JSObject *> baseURL;
2121
static JS::PersistentRooted<JSString *> defaultBackend;
2222
static bool allowDynamicBackends;
23+
static host_api::BackendConfig defaultDynamicBackendConfig;
2324

2425
static const JSPropertySpec properties[];
2526

‎test-d/experimental.test-d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ expectType<(path: string) => Uint8Array>(includeBytes)
66
expectType<(enabled: boolean) => void>(enableDebugLogging)
77
expectType<(base: URL | null | undefined) => void>(setBaseURL)
88
expectType<(backend: string) => void>(setDefaultBackend)
9-
expectType<(enabled: boolean) => void>(allowDynamicBackends)
9+
expectType<{ (enabled: boolean): void; (defaultConfig: { connectTimeout?: number | undefined; firstByteTimeout?: number | undefined; betweenBytesTimeout?: number | undefined; }): void; }>(allowDynamicBackends)

‎types/experimental.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,9 @@ declare module "fastly:experimental" {
5353
* @experimental
5454
*/
5555
export function allowDynamicBackends(enabled: boolean): void;
56+
export function allowDynamicBackends(defaultConfig: {
57+
connectTimeout?: number;
58+
firstByteTimeout?: number;
59+
betweenBytesTimeout?: number;
60+
}): void;
5661
}

0 commit comments

Comments
 (0)
Please sign in to comment.