May 14, 2019
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?