Skip to content

Commit 4c7b7b1

Browse files
committed
handle graceful shutdown
1 parent 1a4a360 commit 4c7b7b1

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed

src/main.zig

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const Browser = @import("browser/browser.zig").Browser;
3030
const build_config = @import("build_config");
3131
const parser = @import("browser/netsurf.zig");
3232

33+
var _app: ?*App = null;
34+
var _server: ?Server = null;
35+
3336
pub fn main() !void {
3437
// allocator
3538
// - in Debug mode we use the General Purpose Allocator to detect memory leaks
@@ -41,29 +44,42 @@ pub fn main() !void {
4144
if (gpa.detectLeaks()) std.posix.exit(1);
4245
};
4346

44-
// Exit the program on SIGINT signal. When running the browser in a Docker
45-
// container, sending a CTRL-C (SIGINT) signal is catched but doesn't exit
46-
// the program. Here we force exiting on SIGINT.
47-
std.posix.sigaction(std.posix.SIG.INT, &std.posix.Sigaction{
47+
run(alloc) catch |err| {
48+
// If explicit filters were set, they won't be valid anymore because
49+
// the args_arena is gone. We need to set it to something that's not
50+
// invalid. (We should just move the args_arena up to main)
51+
log.opts.filter_scopes = &.{};
52+
log.fatal(.app, "exit", .{ .err = err });
53+
std.posix.exit(1);
54+
};
55+
}
56+
57+
// Handle app shutdown gracefuly on signals.
58+
fn shutdown() void {
59+
const sigaction: std.posix.Sigaction = .{
4860
.handler = .{
4961
.handler = struct {
5062
pub fn handler(_: c_int) callconv(.c) void {
63+
// Shutdown service gracefuly.
64+
if (_server) |server| {
65+
server.deinit();
66+
}
67+
if (_app) |app| {
68+
app.deinit();
69+
}
5170
std.posix.exit(0);
5271
}
5372
}.handler,
5473
},
5574
.mask = std.posix.empty_sigset,
5675
.flags = 0,
57-
}, null);
58-
59-
run(alloc) catch |err| {
60-
// If explicit filters were set, they won't be valid anymore because
61-
// the args_arena is gone. We need to set it to something that's not
62-
// invalid. (We should just move the args_arena up to main)
63-
log.opts.filter_scopes = &.{};
64-
log.fatal(.app, "exit", .{ .err = err });
65-
std.posix.exit(1);
6676
};
77+
// Exit the program on SIGINT signal. When running the browser in a Docker
78+
// container, sending a CTRL-C (SIGINT) signal is catched but doesn't exit
79+
// the program. Here we force exiting on SIGINT.
80+
std.posix.sigaction(std.posix.SIG.INT, &sigaction, null);
81+
std.posix.sigaction(std.posix.SIG.TERM, &sigaction, null);
82+
std.posix.sigaction(std.posix.SIG.QUIT, &sigaction, null);
6783
}
6884

6985
fn run(alloc: Allocator) !void {
@@ -96,7 +112,8 @@ fn run(alloc: Allocator) !void {
96112
const platform = try Platform.init();
97113
defer platform.deinit();
98114

99-
var app = try App.init(alloc, .{
115+
// _app is global to handle graceful shutdown.
116+
_app = try App.init(alloc, .{
100117
.run_mode = args.mode,
101118
.platform = &platform,
102119
.http_proxy = args.httpProxy(),
@@ -107,6 +124,7 @@ fn run(alloc: Allocator) !void {
107124
.http_max_host_open = args.httpMaxHostOpen(),
108125
.http_max_concurrent = args.httpMaxConcurrent(),
109126
});
127+
const app = _app.?;
110128
defer app.deinit();
111129
app.telemetry.record(.{ .run = {} });
112130

@@ -118,7 +136,9 @@ fn run(alloc: Allocator) !void {
118136
return args.printUsageAndExit(false);
119137
};
120138

121-
var server = try Server.init(app, address);
139+
// _server is global to handle graceful shutdown.
140+
_server = try Server.init(app, address);
141+
const server = &_server.?;
122142
defer server.deinit();
123143

124144
server.run(address, opts.timeout) catch |err| {

0 commit comments

Comments
 (0)