On 9/22/20 2:32 AM, drathier wrote:> What's the obvious way to put a timeout around a function call? I'm
> thinking a 5 or 30 second timeout, and I'm expecting it to pretty much
> never time out.

I would start a thread and use receiveTimeout():

import std.concurrency;
import std.stdio;
import std.exception;
import core.thread;

// Uncomment to see what happens upon time out.
// version = doTimeout;

void compute(int i) {
  version (doTimeout) {
    writeln("The thread is napping.");
    Thread.sleep(2.seconds);
  }
  ownerTid.send(i + 1);
}

void main() {
  auto worker = spawn(&compute, 42);
  const received = receiveTimeout(
    1.seconds,

    (int result) {
      writefln!"Received the result: %s"(result);
    }
  );

  enforce(received, "Timed out.");
}

The thread need not be one-shot: It can continue waiting for more messages until told to stop:

import std.concurrency;
import std.stdio;
import std.exception;
import core.thread;

// Uncomment to see what happens upon time out.
// version = doTimeout;

struct Done {
}

void computer() {
  bool done = false;
  while (!done) {
    receive(
      (Done _) {
        done = true;
      },

      (int i) {
        version (doTimeout) {
          writeln("The thread is napping.");
          Thread.sleep(2.seconds);
        }
        ownerTid.send(i + 1);
      }
    );
  }
}

void main() {
  // This time we use spawnLinked() so that we will receive
  // a LinkTerminated message. And the name is different and
  // the argument will be passed later with send().
  auto worker = spawnLinked(&computer);

  foreach (i; 0 .. 10) {
    worker.send(i);
    const received = receiveTimeout(
      1.seconds,

      (int result) {
        writefln!"Received the result: %s"(result);
      }
    );

    enforce(received, "Timed out.");
  }

  // Tell worker to stop.
  worker.send(Done());

  // Wait for worker to terminate.
  receiveOnly!LinkTerminated();
}

Ali

Reply via email to