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.