Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions integration-tests/js-compute/fixtures/app/src/logger.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Logger } from "fastly:logger";
import { routes, isRunningLocally } from "./routes";

const earlyLogger = new Logger("AnotherLog");

routes.set("/logger", () => {
if (isRunningLocally()) {
let logger = new Logger("ComputeLog");
logger.log("Hello!");
earlyLogger.log("World!");
}

return new Response();
Expand Down
6 changes: 1 addition & 5 deletions runtime/fastly/builtins/fastly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,7 @@ bool Fastly::getLogger(JSContext *cx, unsigned argc, JS::Value *vp) {
if (!args.requireAtLeast(cx, "fastly.getLogger", 1))
return false;

auto name = core::encode(cx, args[0]);
if (!name)
return false;

JS::RootedObject logger(cx, Logger::create(cx, name.begin()));
JS::RootedObject logger(cx, Logger::create(cx, args[0]));
if (!logger) {
return false;
}
Expand Down
51 changes: 29 additions & 22 deletions runtime/fastly/builtins/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,31 @@ namespace fastly::logger {
bool Logger::log(JSContext *cx, unsigned argc, JS::Value *vp) {
METHOD_HEADER(1)

host_api::LogEndpoint endpoint(JS::GetReservedSlot(self, Logger::Slots::Endpoint).toInt32());
JS::RootedValue endpoint_id(cx, JS::GetReservedSlot(self, Slots::Endpoint));

// If the endpoint has not yet been loaded up, do it now, throwing any endpoint error for the
// first log.
if (endpoint_id.isNull()) {
JS::RootedString endpoint_name(cx, JS::GetReservedSlot(self, Slots::EndpointName).toString());
auto endpoint_name_str = core::encode(cx, endpoint_name);
if (!endpoint_name_str) {
return false;
}

auto res = host_api::LogEndpoint::get(
std::string_view{endpoint_name_str.ptr.get(), endpoint_name_str.len});
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return false;
}

endpoint_id.set(JS::Int32Value(res.unwrap().handle));
JS::SetReservedSlot(self, Slots::Endpoint, endpoint_id);

MOZ_ASSERT(endpoint_id.isInt32());
}

host_api::LogEndpoint endpoint(endpoint_id.toInt32());

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

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

JSObject *Logger::create(JSContext *cx, const char *name) {
JSObject *Logger::create(JSContext *cx, JS::HandleValue endpoint_name) {
JS::RootedObject logger(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
if (!logger) {
return nullptr;
}

auto res = host_api::LogEndpoint::get(std::string_view{name, strlen(name)});
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return nullptr;
}

JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(res.unwrap().handle));

JS::SetReservedSlot(logger, Slots::Endpoint, JS::NullValue());
JS::SetReservedSlot(logger, Slots::EndpointName, endpoint_name);
return logger;
}

bool Logger::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
REQUEST_HANDLER_ONLY("The Logger builtin");
CTOR_HEADER("Logger", 1);

auto name = core::encode(cx, args[0]);
auto handle_res = host_api::LogEndpoint::get(name);
if (auto *err = handle_res.to_err()) {
HANDLE_ERROR(cx, *err);
return false;
}

JS::RootedObject logger(cx, JS_NewObjectForConstructor(cx, &class_, args));
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(handle_res.unwrap().handle));
auto logger = Logger::create(cx, args[0]);
args.rval().setObject(*logger);
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/fastly/builtins/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ class Logger : public builtins::BuiltinImpl<Logger> {
static constexpr const char *class_name = "Logger";
static const int ctor_length = 1;

enum Slots { Endpoint, Count };
enum Slots { Endpoint, EndpointName, Count };
static const JSFunctionSpec static_methods[];
static const JSPropertySpec static_properties[];
static const JSFunctionSpec methods[];
static const JSPropertySpec properties[];

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

Expand Down
9 changes: 1 addition & 8 deletions runtime/js-compute-runtime/builtins/fastly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,14 @@ bool Fastly::getGeolocationForIpAddress(JSContext *cx, unsigned argc, JS::Value
return JS_ParseJSON(cx, geo_info_str, args.rval());
}

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

auto name = core::encode(cx, args[0]);
if (!name)
return false;

JS::RootedObject logger(cx, builtins::Logger::create(cx, name.begin()));
JS::RootedObject logger(cx, builtins::Logger::create(cx, args[0]));
if (!logger) {
return false;
}
Expand Down
51 changes: 29 additions & 22 deletions runtime/js-compute-runtime/builtins/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,31 @@ namespace builtins {
bool Logger::log(JSContext *cx, unsigned argc, JS::Value *vp) {
METHOD_HEADER(1)

host_api::LogEndpoint endpoint(JS::GetReservedSlot(self, Logger::Slots::Endpoint).toInt32());
JS::RootedValue endpoint_id(cx, JS::GetReservedSlot(self, Slots::Endpoint));

// If the endpoint has not yet been loaded up, do it now, throwing any endpoint error for the
// first log.
if (endpoint_id.isNull()) {
JS::RootedString endpoint_name(cx, JS::GetReservedSlot(self, Slots::EndpointName).toString());
auto endpoint_name_str = core::encode(cx, endpoint_name);
if (!endpoint_name_str) {
return false;
}

auto res = host_api::LogEndpoint::get(
std::string_view{endpoint_name_str.ptr.get(), endpoint_name_str.len});
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return false;
}

endpoint_id.set(JS::Int32Value(res.unwrap().handle));
JS::SetReservedSlot(self, Slots::Endpoint, endpoint_id);

MOZ_ASSERT(endpoint_id.isInt32());
}

host_api::LogEndpoint endpoint(endpoint_id.toInt32());

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

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

JSObject *Logger::create(JSContext *cx, const char *name) {
JSObject *Logger::create(JSContext *cx, JS::HandleValue endpoint_name) {
JS::RootedObject logger(cx, JS_NewObjectWithGivenProto(cx, &class_, proto_obj));
if (!logger) {
return nullptr;
}

auto res = host_api::LogEndpoint::get(std::string_view{name, strlen(name)});
if (auto *err = res.to_err()) {
HANDLE_ERROR(cx, *err);
return nullptr;
}

JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(res.unwrap().handle));

JS::SetReservedSlot(logger, Slots::Endpoint, JS::NullValue());
JS::SetReservedSlot(logger, Slots::EndpointName, endpoint_name);
return logger;
}

bool Logger::constructor(JSContext *cx, unsigned argc, JS::Value *vp) {
REQUEST_HANDLER_ONLY("The Logger builtin");
CTOR_HEADER("Logger", 1);

auto name = core::encode(cx, args[0]);
auto handle_res = host_api::LogEndpoint::get(name);
if (auto *err = handle_res.to_err()) {
HANDLE_ERROR(cx, *err);
return false;
}

JS::RootedObject logger(cx, JS_NewObjectForConstructor(cx, &class_, args));
JS::SetReservedSlot(logger, Slots::Endpoint, JS::Int32Value(handle_res.unwrap().handle));
auto logger = Logger::create(cx, args[0]);
args.rval().setObject(*logger);
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/js-compute-runtime/builtins/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ class Logger : public BuiltinImpl<Logger> {
static constexpr const char *class_name = "Logger";
static const int ctor_length = 1;

enum Slots { Endpoint, Count };
enum Slots { Endpoint, EndpointName, Count };
static const JSFunctionSpec static_methods[];
static const JSPropertySpec static_properties[];
static const JSFunctionSpec methods[];
static const JSPropertySpec properties[];

static JSObject *create(JSContext *cx, const char *name);
static JSObject *create(JSContext *cx, JS::HandleValue endpoint_name);
static bool constructor(JSContext *cx, unsigned argc, JS::Value *vp);
static bool init_class(JSContext *cx, JS::HandleObject global);
};
Expand Down