RejectedSoftware Forums

Sign up

How to interact with worker tasks?

Hello,

I'm a complete newbie to vibe.d, although I use most other RejectedSoftware stuff :D

With runTask we get a Task in return, and we can join it and such. This is not the case with runWorkerTaskDist.

import std.stdio;
import vibe.core.core;

void main()
{
    enableWorkerThreads();
    runWorkerTaskDist({
    	writeln("Hello world!");
    });
}

It has no return type. So how can we join it so above example terminates fully?

Re: How to interact with worker tasks?

On Sun, 19 Jan 2014 08:13:13 GMT, Kelet wrote:

Hello,

I'm a complete newbie to vibe.d, although I use most other RejectedSoftware stuff :D

With runTask we get a Task in return, and we can join it and such. This is not the case with runWorkerTaskDist.

import std.stdio;
import vibe.core.core;

void main()
{
    enableWorkerThreads();
    runWorkerTaskDist({
    	writeln("Hello world!");
    });
}

It has no return type. So how can we join it so above example terminates fully?

The easiest way to get the task handle is to use vibe.core.concurrency (the task handle isn't returned from runWorkerTask(Dist) for performance reasons):

void main()
{
    runWorkerTask((parent){
        parent.send(Task.getThis());
        writeln("Hello world!");
    }, Task.getThis());
    auto task = receiveOnly!Task();
}

runWorkerTaskDist starts a task in each worker thread, so to record all of them, this should work:

void main()
{
    runWorkerTask((parent){
        parent.send(Task.getThis());
        writeln("Hello world!");
    }, Task.getThis());
    Task[] tasks;
    foreach (i; 0 .. workerThreadCount)
        tasks ~= receiveOnly!Task();
}

The problem though is that joining and interrupting tasks across threads isn't yet implemented. But you can simulate that using a TaskCondition:

__gshared TaskCondition g_joinCondition;
__gshared Mutex g_joinMutex;
__gshared bool g_taskFinished = false;

void main()
{
    g_joinMutex = new Mutex;
    g_joinCondition = new TaskCondition(g_joinMutex);

    runWorkerTask({
        writeln("Hello world!");

        // signal that the task has finished
        synchronized (g_joinMutex) g_taskFinished = true;
        g_joinCondition.notifyAll();
    });

    // wait for tastk to finish
    synchronized (g_joinMutex)
        while (!g_taskFinished)
            g_joinCondition.wait();
}

Re: How to interact with worker tasks?

Hi Sönke,

Thanks for the reply. Just getting around to processing it now.

On Sun, 19 Jan 2014 14:24:09 GMT, Sönke Ludwig wrote:

void main()
{
    runWorkerTask((parent){
        parent.send(Task.getThis());
        writeln("Hello world!");
    }, Task.getThis());
    auto task = receiveOnly!Task();
}

This does not work. The first problem is that (parent) should probably be (Task parent). After changing this, I get

object.Error: Access ViolationCoreTaskFiber was terminated unexpectedly: Invalid task handle

on the receiveOnly!Task(); line.

Re: How to interact with worker tasks?

On Sun, 19 Jan 2014 14:24:09 GMT, Sönke Ludwig wrote:

void main()
{
    runWorkerTask((parent){
        parent.send(Task.getThis());
        writeln("Hello world!");
    }, Task.getThis());
    auto task = receiveOnly!Task();
}

Also, why the send before the writeln?