Context in D Programming Language

Here’s the translation of the Go code example to D, formatted in Markdown suitable for Hugo:

In the previous example we looked at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of core.sync.Mutex for controlling cancellation. A Mutex carries deadlines, cancellation signals, and other request-scoped values across API boundaries and threads.

import std.stdio;
import std.datetime;
import vibe.vibe;

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
    writeln("server: hello handler started");
    scope(exit) writeln("server: hello handler ended");

    // A Mutex is created for each request
    auto mutex = new core.sync.Mutex();

    // Simulate work
    auto done = false;
    auto workerThread = new Thread({
        Thread.sleep(10.seconds);
        synchronized(mutex) {
            if (!done) {
                res.writeBody("hello\n");
                done = true;
            }
        }
    });
    workerThread.start();

    // Wait for the work to complete or for cancellation
    auto startTime = Clock.currTime();
    while (Clock.currTime() - startTime < 11.seconds)
    {
        if (req.clientDisconnected)
        {
            synchronized(mutex) {
                if (!done) {
                    writeln("server: client disconnected");
                    res.statusCode = HTTPStatus.internalServerError;
                    res.writeBody("Operation cancelled");
                    done = true;
                }
            }
            break;
        }
        Thread.sleep(100.msecs);
    }

    workerThread.join();
}

void main()
{
    auto settings = new HTTPServerSettings;
    settings.port = 8090;
    settings.bindAddresses = ["::1", "127.0.0.1"];

    listenHTTP(settings, &hello);

    runApplication();
}

Run the server in the background.

$ dub run &

Simulate a client request to /hello, hitting Ctrl+C shortly after starting to signal cancellation.

$ curl localhost:8090/hello
server: hello handler started
^C
server: client disconnected
server: hello handler ended

In this D version, we use Vibe.d, a popular asynchronous I/O and web framework for D. We simulate the context cancellation using a Mutex and by checking for client disconnection. The synchronized block is used to ensure thread-safe access to shared variables.

Note that D doesn’t have a direct equivalent to Go’s context.Context, so we’ve adapted the example to use D’s concurrency primitives while maintaining similar functionality.