aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-16 00:53:03 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-16 00:53:03 -0700
commit0ce709d96abb48c747f5c93033c9a80fe79ee3bc (patch)
treef535a53c23fd95154b36ceab7c38c8e3a0275c89 /src/bun.js/api
parentfd808dec524c60ba18c620e27b205828760a6e41 (diff)
downloadbun-0ce709d96abb48c747f5c93033c9a80fe79ee3bc.tar.gz
bun-0ce709d96abb48c747f5c93033c9a80fe79ee3bc.tar.zst
bun-0ce709d96abb48c747f5c93033c9a80fe79ee3bc.zip
Make new HTTP client more stable
Diffstat (limited to 'src/bun.js/api')
-rw-r--r--src/bun.js/api/bun.zig34
-rw-r--r--src/bun.js/api/server.zig50
2 files changed, 60 insertions, 24 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index a37d5d62c..3fafdc177 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -1101,6 +1101,9 @@ pub const Class = NewClass(
.nanoseconds = .{
.rfn = nanoseconds,
},
+ .DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump = .{
+ .rfn = dump_mimalloc,
+ },
.gzipSync = .{
.rfn = JSC.wrapWithHasContainer(JSZlib, "gzipSync", false, false, true),
},
@@ -1191,6 +1194,18 @@ pub const Class = NewClass(
},
);
+fn dump_mimalloc(
+ _: void,
+ globalThis: JSC.C.JSContextRef,
+ _: JSC.C.JSObjectRef,
+ _: JSC.C.JSObjectRef,
+ _: []const JSC.C.JSValueRef,
+ _: JSC.C.ExceptionRef,
+) JSC.C.JSValueRef {
+ globalThis.bunVM().arena.dumpThreadStats();
+ return JSC.JSValue.jsUndefined().asObjectRef();
+}
+
pub const Crypto = struct {
const Hashers = @import("../../sha.zig");
@@ -2101,6 +2116,8 @@ pub const Timer = struct {
return VirtualMachine.vm.timer.last_id;
}
+ const Pool = bun.ObjectPool(Timeout, null, true, 1000);
+
pub const Timeout = struct {
id: i32 = 0,
callback: JSValue,
@@ -2134,11 +2151,13 @@ pub const Timer = struct {
if (comptime JSC.is_bindgen)
unreachable;
+ var vm = global.bunVM();
+
if (!this.cancelled) {
if (this.repeat) {
this.io_task.?.deinit();
- var task = Timeout.TimeoutTask.createOnJSThread(VirtualMachine.vm.allocator, global, this) catch unreachable;
- VirtualMachine.vm.timer.timeouts.put(VirtualMachine.vm.allocator, this.id, this) catch unreachable;
+ var task = Timeout.TimeoutTask.createOnJSThread(vm.allocator, global, this) catch unreachable;
+ vm.timer.timeouts.put(vm.allocator, this.id, this) catch unreachable;
this.io_task = task;
task.schedule();
}
@@ -2148,12 +2167,12 @@ pub const Timer = struct {
if (this.repeat)
return;
- VirtualMachine.vm.timer.active -|= 1;
- VirtualMachine.vm.active_tasks -|= 1;
+ vm.timer.active -|= 1;
+ vm.active_tasks -|= 1;
} else {
// the active tasks count is already cleared for canceled timeout,
// add one here to neutralize the `-|= 1` in event loop.
- VirtualMachine.vm.active_tasks +|= 1;
+ vm.active_tasks +|= 1;
}
this.clear(global);
@@ -2168,8 +2187,9 @@ pub const Timer = struct {
_ = VirtualMachine.vm.timer.timeouts.swapRemove(this.id);
if (this.io_task) |task| {
task.deinit();
+ this.io_task = null;
}
- VirtualMachine.vm.allocator.destroy(this);
+ Pool.releaseValue(this);
}
};
@@ -2181,7 +2201,7 @@ pub const Timer = struct {
repeat: bool,
) !void {
if (comptime is_bindgen) unreachable;
- var timeout = try VirtualMachine.vm.allocator.create(Timeout);
+ var timeout = Pool.first(globalThis.bunVM().allocator);
js.JSValueProtect(globalThis.ref(), callback.asObjectRef());
timeout.* = Timeout{ .id = id, .callback = callback, .interval = countdown.toInt32(), .repeat = repeat };
var task = try Timeout.TimeoutTask.createOnJSThread(VirtualMachine.vm.allocator, globalThis, timeout);
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index b79e6c7ab..55b829caa 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -1850,6 +1850,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
has_js_deinited: bool = false,
listen_callback: JSC.AnyTask = undefined,
allocator: std.mem.Allocator,
+ keeping_js_alive: bool = false,
pub const Class = JSC.NewClass(
ThisServer,
@@ -1917,15 +1918,17 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
}
pub fn deinitIfWeCan(this: *ThisServer) void {
- if (this.pending_requests == 0 and this.listener == null and this.has_js_deinited)
+ if (this.pending_requests == 0 and this.listener == null and this.has_js_deinited) {
+ this.deref();
this.deinit();
+ }
}
pub fn stop(this: *ThisServer) void {
if (this.listener) |listener| {
- listener.close();
this.listener = null;
- this.vm.disable_run_us_loop = false;
+ this.deref();
+ listener.close();
}
this.deinitIfWeCan();
@@ -2038,22 +2041,26 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
this.listener = socket;
const needs_post_handler = this.vm.uws_event_loop == null;
this.vm.uws_event_loop = uws.Loop.get();
- this.listen_callback = JSC.AnyTask.New(ThisServer, run).init(this);
- this.vm.eventLoop().enqueueTask(JSC.Task.init(&this.listen_callback));
+ this.ref();
+
if (needs_post_handler) {
_ = this.vm.uws_event_loop.?.addPostHandler(*JSC.EventLoop, this.vm.eventLoop(), JSC.EventLoop.tick);
+ _ = this.vm.uws_event_loop.?.addPreHandler(*JSC.EventLoop, this.vm.eventLoop(), JSC.EventLoop.tick);
}
}
- pub fn run(this: *ThisServer) void {
- // this.app.addServerName(hostname_pattern: [*:0]const u8)
+ pub fn ref(this: *ThisServer) void {
+ if (this.keeping_js_alive) return;
+
+ this.vm.us_loop_reference_count +|= 1;
+ this.keeping_js_alive = true;
+ }
- // we do not increment the reference count here
- // uWS manages running the loop, so it is unnecessary
- // this.vm.us_loop_reference_count +|= 1;
- this.vm.disable_run_us_loop = true;
+ pub fn deref(this: *ThisServer) void {
+ if (!this.keeping_js_alive) return;
- this.app.run();
+ this.vm.us_loop_reference_count -|= 1;
+ this.keeping_js_alive = false;
}
pub fn onBunInfoRequest(this: *ThisServer, req: *uws.Request, resp: *App.Response) void {
@@ -2286,11 +2293,20 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type {
this.app.get("/src:/*", *ThisServer, this, onSrcRequest);
}
- this.app.listenWithConfig(*ThisServer, this, onListen, .{
- .port = this.config.port,
- .host = this.config.hostname,
- .options = 0,
- });
+ const hostname = bun.span(this.config.hostname);
+
+ if (!(hostname.len == 0 or strings.eqlComptime(hostname, "0.0.0.0"))) {
+ this.app.listenWithConfig(*ThisServer, this, onListen, .{
+ .port = this.config.port,
+ .options = 0,
+ });
+ } else {
+ this.app.listenWithConfig(*ThisServer, this, onListen, .{
+ .port = this.config.port,
+ .host = this.config.hostname,
+ .options = 0,
+ });
+ }
}
};
}