Arm the watchdog for every mode, not just snapshot
The watchdog was spawned inside snapshot.run, so legacy highlights mode ran without it. That is the mode NickelMenu invokes, against the endpoint that stopped responding and hung a run for 16 days — so the exact failure being fixed was still reachable from the device's menu. Moves the spawn into main, ahead of mode dispatch, so both paths are covered. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -169,15 +169,19 @@ pub fn main() !void {
|
|||||||
std.fmt.parseInt(u64, args[4], 10) catch snapshot.default_timeout_secs
|
std.fmt.parseInt(u64, args[4], 10) catch snapshot.default_timeout_secs
|
||||||
else
|
else
|
||||||
snapshot.default_timeout_secs;
|
snapshot.default_timeout_secs;
|
||||||
|
try snapshot.startWatchdog(timeout);
|
||||||
return snapshot.run(
|
return snapshot.run(
|
||||||
allocator,
|
allocator,
|
||||||
args[2],
|
args[2],
|
||||||
if (args.len >= 4) args[3] else null,
|
if (args.len >= 4) args[3] else null,
|
||||||
snapshot.default_snapshot_path,
|
snapshot.default_snapshot_path,
|
||||||
timeout,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy mode uploads too, so it needs the same protection: the endpoint it posts to
|
||||||
|
// is what hung a run for 16 days.
|
||||||
|
try snapshot.startWatchdog(snapshot.default_timeout_secs);
|
||||||
|
|
||||||
// `highlights <db> [endpoint]`, or the legacy `<db> [endpoint]` form.
|
// `highlights <db> [endpoint]`, or the legacy `<db> [endpoint]` form.
|
||||||
const legacy = std.mem.eql(u8, args[1], "highlights");
|
const legacy = std.mem.eql(u8, args[1], "highlights");
|
||||||
const rest = if (legacy) args[2..] else args[1..];
|
const rest = if (legacy) args[2..] else args[1..];
|
||||||
|
|||||||
+8
-4
@@ -35,6 +35,13 @@ fn watchdog(secs: u64) void {
|
|||||||
std.process.exit(2);
|
std.process.exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Arm the watchdog for the current process. Every mode needs this, not just snapshot:
|
||||||
|
/// legacy highlights mode POSTs to the same kind of endpoint and hangs the same way.
|
||||||
|
pub fn startWatchdog(secs: u64) !void {
|
||||||
|
const guard = try std.Thread.spawn(.{}, watchdog, .{secs});
|
||||||
|
guard.detach();
|
||||||
|
}
|
||||||
|
|
||||||
fn sha256Hex(data: []const u8, out: *[64]u8) void {
|
fn sha256Hex(data: []const u8, out: *[64]u8) void {
|
||||||
var digest: [32]u8 = undefined;
|
var digest: [32]u8 = undefined;
|
||||||
std.crypto.hash.sha2.Sha256.hash(data, &digest, .{});
|
std.crypto.hash.sha2.Sha256.hash(data, &digest, .{});
|
||||||
@@ -97,16 +104,13 @@ fn writeSnapshot(allocator: std.mem.Allocator, db_path: []const u8, snap_path: [
|
|||||||
if (c.sqlite3_close(db) != c.SQLITE_OK) return error.DatabaseCloseFailed;
|
if (c.sqlite3_close(db) != c.SQLITE_OK) return error.DatabaseCloseFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Caller is expected to have armed `startWatchdog` already.
|
||||||
pub fn run(
|
pub fn run(
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
db_path: []const u8,
|
db_path: []const u8,
|
||||||
endpoint: ?[]const u8,
|
endpoint: ?[]const u8,
|
||||||
snap_path: []const u8,
|
snap_path: []const u8,
|
||||||
timeout_secs: u64,
|
|
||||||
) !void {
|
) !void {
|
||||||
const guard = try std.Thread.spawn(.{}, watchdog, .{timeout_secs});
|
|
||||||
guard.detach();
|
|
||||||
|
|
||||||
try writeSnapshot(allocator, db_path, snap_path);
|
try writeSnapshot(allocator, db_path, snap_path);
|
||||||
// Database handle is released from here on.
|
// Database handle is released from here on.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user