diff options
author | 2023-01-12 19:27:21 -0800 | |
---|---|---|
committer | 2023-01-12 19:38:27 -0800 | |
commit | 62cab3c719aafbf0a41d08276e0fd038ca5a67ea (patch) | |
tree | bdf3eb74891eb8e49c2725f59646be264b070f88 | |
parent | d4f1d29393f86cac475806d8308abe06121f1251 (diff) | |
download | bun-62cab3c719aafbf0a41d08276e0fd038ca5a67ea.tar.gz bun-62cab3c719aafbf0a41d08276e0fd038ca5a67ea.tar.zst bun-62cab3c719aafbf0a41d08276e0fd038ca5a67ea.zip |
[Bun.serve] Add flag to close all connections
-rw-r--r-- | src/bun.js/api/server.zig | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 137d164f0..0060924d7 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -3859,13 +3859,17 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { config: ServerConfig = ServerConfig{}, pending_requests: usize = 0, request_pool_allocator: std.mem.Allocator = undefined, - has_js_deinited: bool = false, listen_callback: JSC.AnyTask = undefined, allocator: std.mem.Allocator, poll_ref: JSC.PollRef = .{}, - deinit_scheduled: bool = false, temporary_url_buffer: std.ArrayListUnmanaged(u8) = .{}, + flags: packed struct(u3) { + deinit_scheduled: bool = false, + terminated: bool = false, + has_js_deinited: bool = false, + } = .{}, + pub const Class = JSC.NewClass( ThisServer, .{ .name = "Server" }, @@ -3980,6 +3984,11 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { JSC.throwInvalidArguments("To enable websocket support, set the \"websocket\" object in Bun.serve({})", .{}, globalThis, exception); return JSValue.jsUndefined(); } + + if (this.flags.terminated) { + return JSValue.jsBoolean(false); + } + var request = object.as(Request) orelse { JSC.throwInvalidArguments("upgrade requires a Request object", .{}, globalThis, exception); return JSValue.jsUndefined(); @@ -4281,11 +4290,20 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { return JSC.JSPromise.resolvedPromiseValue(ctx, response_value).asObjectRef(); } - pub fn stopFromJS(this: *ThisServer) JSC.JSValue { + pub fn stopFromJS(this: *ThisServer, abruptly: ?JSValue) JSC.JSValue { if (this.listener != null) { + const abrupt = brk: { + if (abruptly) |val| { + if (val.isBoolean() and val.toBoolean()) { + break :brk true; + } + } + break :brk false; + }; + JSC.C.JSValueUnprotect(this.globalThis, this.thisObject.asObjectRef()); this.thisObject = JSC.JSValue.jsUndefined(); - this.stop(); + this.stop(abrupt); } return JSC.JSValue.jsUndefined(); @@ -4330,7 +4348,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { pub fn finalize(this: *ThisServer) void { httplog("finalize", .{}); - this.has_js_deinited = true; + this.flags.has_js_deinited = true; this.deinitIfWeCan(); } @@ -4345,7 +4363,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { pub fn deinitIfWeCan(this: *ThisServer) void { httplog("deinitIfWeCan", .{}); - if (this.pending_requests == 0 and this.listener == null and this.has_js_deinited and !this.hasActiveWebSockets()) { + if (this.pending_requests == 0 and this.listener == null and this.flags.has_js_deinited and !this.hasActiveWebSockets()) { if (this.config.websocket) |*ws| { ws.handler.app = null; } @@ -4354,23 +4372,34 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { } } - pub fn stopListening(this: *ThisServer) void { + pub fn stopListening(this: *ThisServer, abrupt: bool) void { var listener = this.listener orelse return; this.listener = null; this.unref(); - listener.close(); + if (!abrupt) { + listener.close(); + } else { + this.flags.terminated = true; + this.app.close(); + } } - pub fn stop(this: *ThisServer) void { - this.stopListening(); + pub fn stop(this: *ThisServer, abrupt: bool) void { + this.stopListening(abrupt); this.deinitIfWeCan(); } pub fn scheduleDeinit(this: *ThisServer) void { - if (this.deinit_scheduled) + if (this.flags.deinit_scheduled) return; - this.deinit_scheduled = true; + this.flags.deinit_scheduled = true; httplog("scheduleDeinit", .{}); + + if (!this.flags.terminated) { + this.flags.terminated = true; + this.app.close(); + } + var task = bun.default_allocator.create(JSC.AnyTask) catch unreachable; task.* = JSC.AnyTask.New(ThisServer, deinit).init(this); this.vm.enqueueTask(JSC.Task.init(task)); |