Re: Timeout around function call

2020-09-27 Thread drathier via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 20:58:00 UTC, Imperatorn wrote:
On Wednesday, 23 September 2020 at 20:54:51 UTC, Imperatorn 
wrote:
On Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli 
wrote:

On 9/23/20 1:19 PM, Imperatorn wrote:

> [...]
send a
> [...]
with timeout.

[...]


Sorry, I can't see the problem. Could you be more specific 
about what you want to achieve?


Oops, I meant to reply to drathier


I need to:

- call a side-effect-free fn with a huge argument that I don't 
want to copy; this argument is then returned mostly unmodified 
wrapped in a new value

- stop executing it if it runs for more than x seconds
- get the return value from it if it finishes within x seconds 
(99.9% of time time)

- let the main thread know what happened
- the main thread should block until the fn call returns
- the fn call should for sure stop executing before the main 
thread carries on
- the size and complexity of the fn makes it pretty much 
impossible to add timeout checks everywhere to make it exit 
nicely; I need to kill it to be sure I didn't miss a case






Re: Timeout around function call

2020-09-23 Thread Imperatorn via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 20:54:51 UTC, Imperatorn wrote:
On Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli 
wrote:

On 9/23/20 1:19 PM, Imperatorn wrote:

> [...]
send a
> [...]
with timeout.

[...]


Sorry, I can't see the problem. Could you be more specific 
about what you want to achieve?


Oops, I meant to reply to drathier


Re: Timeout around function call

2020-09-23 Thread Imperatorn via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 20:44:51 UTC, Ali Çehreli 
wrote:

On 9/23/20 1:19 PM, Imperatorn wrote:

> [...]
send a
> [...]
with timeout.

[...]


Sorry, I can't see the problem. Could you be more specific about 
what you want to achieve?


Re: Timeout around function call

2020-09-23 Thread Ali Çehreli via Digitalmars-d-learn

On 9/23/20 1:19 PM, Imperatorn wrote:

> No. You should not share anything. Personally I would just send a
> message to request termination or use the solution provided with timeout.

std.concurrency does not allow "mutable thread-local data"; so one needs 
to cast to shared (assuming copying is not desired e.g. because it's 
expensive). I am modifying my second program[1] with these changes:


The worker's receive() call mentions an element with shared ints:

receive(
  // .. same as before

  // New message type:
  (shared(int)[] arr) {
ownerTid.send(arr[0]);
  }
);

The sender casts to shared and receives a shared(int):

  auto arr = new int[100];
  worker.send(cast(shared)arr);
  writefln!"Received array result: %s"(receiveOnly!(shared(int))());

It is unfortunate that receiveOnly!int does not work because the 
returned int is just a copy. Well, at least we have a way of 
distinguishing int from shared(int). Is it useful?


Ali

[1] https://forum.dlang.org/post/rkdrql$2uht$1...@digitalmars.com


Re: Timeout around function call

2020-09-23 Thread Imperatorn via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 17:33:50 UTC, drathier wrote:

On Tuesday, 22 September 2020 at 21:55:51 UTC, Imperatorn wrote:

[...]


Blocking is perfectly fine. I'm wondering if I need things to 
be shared now or something? Not used to programming with 
threads. Adding a shared modifier recursively onto every piece 
of data that needs it is a ton of work though.


I don't want to copy the data around since it's many gigabytes, 
but I'm sure there won't be any data races; main thread will 
start 2 threads, one for running the timer and one running the 
function call. The main thread doesn't access the data until 
both the timer and function call threads have stopped 
completely.


No. You should not share anything. Personally I would just send a 
message to request termination or use the solution provided with 
timeout.


Re: Timeout around function call

2020-09-23 Thread drathier via Digitalmars-d-learn

On Tuesday, 22 September 2020 at 21:55:51 UTC, Imperatorn wrote:

On Tuesday, 22 September 2020 at 09:32:13 UTC, 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.


You have several options. Either you use the actor model 
(spawn[Linked]) and send a termination message after a 
specified time. Or you use a task and check for 
yourTask.done(). Or you could create a Thread and check 
isRunning.


(You didn't specify what you wanted to happen and if blocking 
was allowed or not)


Blocking is perfectly fine. I'm wondering if I need things to be 
shared now or something? Not used to programming with threads. 
Adding a shared modifier recursively onto every piece of data 
that needs it is a ton of work though.


I don't want to copy the data around since it's many gigabytes, 
but I'm sure there won't be any data races; main thread will 
start 2 threads, one for running the timer and one running the 
function call. The main thread doesn't access the data until both 
the timer and function call threads have stopped completely.


Re: Timeout around function call

2020-09-22 Thread Imperatorn via Digitalmars-d-learn

On Tuesday, 22 September 2020 at 09:32:13 UTC, 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.


You have several options. Either you use the actor model 
(spawn[Linked]) and send a termination message after a specified 
time. Or you use a task and check for yourTask.done(). Or you 
could create a Thread and check isRunning.


(You didn't specify what you wanted to happen and if blocking was 
allowed or not)


Re: Timeout around function call

2020-09-22 Thread Ali Çehreli via Digitalmars-d-learn
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



Timeout around function call

2020-09-22 Thread drathier via Digitalmars-d-learn
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.