So I'm implementing a watchdog process for my web server, or a
deadman switch as it's called here:
https://www.digitalmars.com/articles/b40.html
But I ran into a problem with filtering watchdog kicks and then
forwarding other I/O through the watchdog process. Here's what I
have done so far:
import std.experimental.all;
immutable watchdogResetMessage = "check";
enum watchdogTriggerTime = 3.seconds;
version (Watchdog) void main(string[] args)
{ while (true)
{ resetPipe = std.process.pipe();
auto server = spawnProcess(["the web server"], stdin,
resetPipe.writeEnd, stderr, null, Config.retainStdout |
Config.suppressConsole);
auto watchdogTriggered = Clock.currTime;
auto outputTask = spawn(function void(File file)
{ foreach(line; file.byLine)
{ if (line == watchdogResetMessage)
ownerTid.send(ubyte(0));
else line.writeln;
}
}, resetPipe.readEnd);
//waits until no reset message is coing
while (watchdogTriggerTime.receiveTimeout((ubyte){})) {}
writeln(Clock.currTime.toISOExtString, ": Server does not
sign life anymore. Restarting.");
server.kill;
server.wait;
}
}
The problem is that this won't pass compilation, because File
contains theard-local indirection and thus cannot be sent to
another theard.
I haven't done any complicated concurrency in D before. What's a
good way to handle this?