Skip to content

Commit 514d014

Browse files
author
Guy Bedford
authored
feat: Allow early logger initialization (#804)
1 parent a1bd16c commit 514d014

File tree

7 files changed

+67
-61
lines changed

7 files changed

+67
-61
lines changed

integration-tests/js-compute/fixtures/app/src/logger.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { Logger } from "fastly:logger";
22
import { routes, isRunningLocally } from "./routes";
33

4+
const earlyLogger = new Logger("AnotherLog");
5+
46
routes.set("/logger", () => {
57
if (isRunningLocally()) {
68
let logger = new Logger("ComputeLog");
79
logger.log("Hello!");
10+
earlyLogger.log("World!");
811
}
912

1013
return new Response();

runtime/fastly/builtins/fastly.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,7 @@ bool Fastly::getLogger(JSContext *cx, unsigned argc, JS::Value *vp) {
9797
if (!args.requireAtLeast(cx, "fastly.getLogger", 1))
9898
return false;
9999

100-
auto name = core::encode(cx, args[0]);
101-
if (!name)
102-
return false;
103-
104-
JS::RootedObject logger(cx, Logger::create(cx, name.begin()));
100+
JS::RootedObject logger(cx, Logger::create(cx, args[0]));
105101
if (!logger) {
106102
return false;
107103
}

runtime/fastly/builtins/logger.cpp

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,31 @@ namespace fastly::logger {
99
bool Logger::log(JSContext *cx, unsigned argc, JS::Value *vp) {
1010
METHOD_HEADER(1)
1111

12-
host_api::LogEndpoint endpoint(JS::GetReservedSlot(self, Logger::Slots::Endpoint).toInt32());
12+
JS::RootedValue endpoint_id(cx, JS::GetReservedSlot(self, Slots::Endpoint));
13+
14+
// If the endpoint has not yet been loaded up, do it now, throwing any endpoint error for the
15+
// first log.
16+
if (endpoint_id.isNull()) {
17+
JS::RootedString endpoint_name(cx, JS::GetReservedSlot(self, Slots::EndpointName).toString());
18+
auto endpoint_name_str = core::encode(cx, endpoint_name);
19+
if (!endpoint_name_str) {
20+
return false;
21+
}
22+
23+
auto res = host_api::LogEndpoint::get(
24+
std::string_view{endpoint_name_str.ptr.get(), endpoint_name_str.len});
25+
if (auto *err = res.to_err()) {
26+
HANDLE_ERROR(cx, *err);
27+
return false;
28+
}
29+
30+
endpoint_id.set(JS::Int32Value(res.unwrap().handle));
31+
JS::SetReservedSlot(self, Slots::Endpoint, endpoint_id);
32+
33+
MOZ_ASSERT(endpoint_id.isInt32());
34+
}
35+
36+
host_api::LogEndpoint endpoint(endpoint_id.toInt32());
1337

1438
auto msg = core::encode(cx, args.get(0));
1539
if (!msg) {
@@ -38,36 +62,19 @@ const JSFunctionSpec Logger::methods[] = {JS_FN("log", log, 1, JSPROP_ENUMERATE)
3862

3963
const JSPropertySpec Logger::properties[] = {JS_PS_END};
4064

41-
JSObject *Logger::create(JSContext *cx, const char *name) {
65+
JSObject *Logger::create(JSContext *cx, JS::HandleValue endpoint_name) {
4266
JS::RootedObject logger(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
4367
if (!logger) {
4468
return nullptr;
4569
}
46-
47-
auto res = host_api::LogEndpoint::get(std::string_view{name, strlen(name)});
48-
if (auto *err = res.to_err()) {
49-
HANDLE_ERROR(cx, *err);
50-
return nullptr;
51-
}
52-
53-
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(res.unwrap().handle));
54-
70+
JS::SetReservedSlot(logger, Slots::Endpoint, JS::NullValue());
71+
JS::SetReservedSlot(logger, Slots::EndpointName, endpoint_name);
5572
return logger;
5673
}
5774

5875
bool Logger::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
59-
REQUEST_HANDLER_ONLY("The Logger builtin");
6076
CTOR_HEADER("Logger", 1);
61-
62-
auto name = core::encode(cx, args[0]);
63-
auto handle_res = host_api::LogEndpoint::get(name);
64-
if (auto *err = handle_res.to_err()) {
65-
HANDLE_ERROR(cx, *err);
66-
return false;
67-
}
68-
69-
JS::RootedObject logger(cx, JS_NewObjectForConstructor(cx, &class_, args));
70-
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(handle_res.unwrap().handle));
77+
auto logger = Logger::create(cx, args[0]);
7178
args.rval().setObject(*logger);
7279
return true;
7380
}

runtime/fastly/builtins/logger.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ class Logger : public builtins::BuiltinImpl<Logger> {
1414
static constexpr const char *class_name = "Logger";
1515
static const int ctor_length = 1;
1616

17-
enum Slots { Endpoint, Count };
17+
enum Slots { Endpoint, EndpointName, Count };
1818
static const JSFunctionSpec static_methods[];
1919
static const JSPropertySpec static_properties[];
2020
static const JSFunctionSpec methods[];
2121
static const JSPropertySpec properties[];
2222

23-
static JSObject *create(JSContext *cx, const char *name);
23+
static JSObject *create(JSContext *cx, JS::HandleValue endpoint_name);
2424
static bool constructor(JSContext *cx, unsigned argc, JS::Value *vp);
2525
};
2626

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,14 @@ bool Fastly::getGeolocationForIpAddress(JSContext *cx, unsigned argc, JS::Value
6767
return JS_ParseJSON(cx, geo_info_str, args.rval());
6868
}
6969

70-
// TODO(performance): consider allowing logger creation during initialization, but then throw
71-
// when trying to log.
72-
// https://github.com/fastly/js-compute-runtime/issues/225
7370
bool Fastly::getLogger(JSContext *cx, unsigned argc, JS::Value *vp) {
7471
JS::CallArgs args = CallArgsFromVp(argc, vp);
7572
REQUEST_HANDLER_ONLY("fastly.getLogger");
7673
JS::RootedObject self(cx, &args.thisv().toObject());
7774
if (!args.requireAtLeast(cx, "fastly.getLogger", 1))
7875
return false;
7976

80-
auto name = core::encode(cx, args[0]);
81-
if (!name)
82-
return false;
83-
84-
JS::RootedObject logger(cx, builtins::Logger::create(cx, name.begin()));
77+
JS::RootedObject logger(cx, builtins::Logger::create(cx, args[0]));
8578
if (!logger) {
8679
return false;
8780
}

runtime/js-compute-runtime/builtins/logger.cpp

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,31 @@ namespace builtins {
77
bool Logger::log(JSContext *cx, unsigned argc, JS::Value *vp) {
88
METHOD_HEADER(1)
99

10-
host_api::LogEndpoint endpoint(JS::GetReservedSlot(self, Logger::Slots::Endpoint).toInt32());
10+
JS::RootedValue endpoint_id(cx, JS::GetReservedSlot(self, Slots::Endpoint));
11+
12+
// If the endpoint has not yet been loaded up, do it now, throwing any endpoint error for the
13+
// first log.
14+
if (endpoint_id.isNull()) {
15+
JS::RootedString endpoint_name(cx, JS::GetReservedSlot(self, Slots::EndpointName).toString());
16+
auto endpoint_name_str = core::encode(cx, endpoint_name);
17+
if (!endpoint_name_str) {
18+
return false;
19+
}
20+
21+
auto res = host_api::LogEndpoint::get(
22+
std::string_view{endpoint_name_str.ptr.get(), endpoint_name_str.len});
23+
if (auto *err = res.to_err()) {
24+
HANDLE_ERROR(cx, *err);
25+
return false;
26+
}
27+
28+
endpoint_id.set(JS::Int32Value(res.unwrap().handle));
29+
JS::SetReservedSlot(self, Slots::Endpoint, endpoint_id);
30+
31+
MOZ_ASSERT(endpoint_id.isInt32());
32+
}
33+
34+
host_api::LogEndpoint endpoint(endpoint_id.toInt32());
1135

1236
auto msg = core::encode(cx, args.get(0));
1337
if (!msg) {
@@ -36,36 +60,19 @@ const JSFunctionSpec Logger::methods[] = {JS_FN("log", log, 1, JSPROP_ENUMERATE)
3660

3761
const JSPropertySpec Logger::properties[] = {JS_PS_END};
3862

39-
JSObject *Logger::create(JSContext *cx, const char *name) {
63+
JSObject *Logger::create(JSContext *cx, JS::HandleValue endpoint_name) {
4064
JS::RootedObject logger(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
4165
if (!logger) {
4266
return nullptr;
4367
}
44-
45-
auto res = host_api::LogEndpoint::get(std::string_view{name, strlen(name)});
46-
if (auto *err = res.to_err()) {
47-
HANDLE_ERROR(cx, *err);
48-
return nullptr;
49-
}
50-
51-
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(res.unwrap().handle));
52-
68+
JS::SetReservedSlot(logger, Slots::Endpoint, JS::NullValue());
69+
JS::SetReservedSlot(logger, Slots::EndpointName, endpoint_name);
5370
return logger;
5471
}
5572

5673
bool Logger::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
57-
REQUEST_HANDLER_ONLY("The Logger builtin");
5874
CTOR_HEADER("Logger", 1);
59-
60-
auto name = core::encode(cx, args[0]);
61-
auto handle_res = host_api::LogEndpoint::get(name);
62-
if (auto *err = handle_res.to_err()) {
63-
HANDLE_ERROR(cx, *err);
64-
return false;
65-
}
66-
67-
JS::RootedObject logger(cx, JS_NewObjectForConstructor(cx, &class_, args));
68-
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(handle_res.unwrap().handle));
75+
auto logger = Logger::create(cx, args[0]);
6976
args.rval().setObject(*logger);
7077
return true;
7178
}

runtime/js-compute-runtime/builtins/logger.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ class Logger : public BuiltinImpl<Logger> {
1414
static constexpr const char *class_name = "Logger";
1515
static const int ctor_length = 1;
1616

17-
enum Slots { Endpoint, Count };
17+
enum Slots { Endpoint, EndpointName, Count };
1818
static const JSFunctionSpec static_methods[];
1919
static const JSPropertySpec static_properties[];
2020
static const JSFunctionSpec methods[];
2121
static const JSPropertySpec properties[];
2222

23-
static JSObject *create(JSContext *cx, const char *name);
23+
static JSObject *create(JSContext *cx, JS::HandleValue endpoint_name);
2424
static bool constructor(JSContext *cx, unsigned argc, JS::Value *vp);
2525
static bool init_class(JSContext *cx, JS::HandleObject global);
2626
};

0 commit comments

Comments
 (0)