Losing worker context when spinning up new threads

40 views
Skip to first unread message

James Cook

unread,
May 6, 2013, 7:26:17 PM5/6/13
to rin...@googlegroups.com
I have some code where I need to use java.lang.Thread instead of the new Worker() approach to spinning up a long lived thread. Unfortunately, these new modules like to use things like WorkerPromise and setTimeout, but these do not work because there is no engine.getCurrentWorker() context in the new Thread.

Here is an example:

function helloWorld() {
    print( 'hello world' );
}

function main() {
    new java.lang.Thread( new java.lang.Runnable( {
        run : helloWorld
    } ) ).start();

    new java.lang.Thread( new java.lang.Runnable( {
        run : function () {
            setTimeout( helloWorld, 0 );
        }
    } ) ).start();
}

if ( require.main === module ) {
    main();
}


The second thread tries to use setTimeout which is this code:

    global.setInterval =  function(callback, delay) {
        var args = Array.slice(arguments, 2);
        delay = Math.max(parseInt(delay, 10) || 0, 1);
        var worker = engine.getCurrentWorker();
        return worker.scheduleInterval(delay, this, callback, args);
    };

The value of worker is undefined, so we have an exception.

Is there a way to "inject" a worker context into my thread, or some other workaround?


Simon Oberhammer

unread,
May 7, 2013, 6:23:43 AM5/7/13
to rin...@googlegroups.com
Is there a way to "inject" a worker context into my thread, or some other workaround?
 
Ringo tries to find the Worker via the ThreadLocal *or* from the scope. So if you inject a function, which was created in a Ringo context, into a native Thread, that could help. That is why examples/swing.js works: a callback, defined in Ringo, is passed into swing. The callback carries the scope with it and setInterval works even though it is being exeucted in a native Thread with no RingoWorker attached.

I guess you have already seen the setInterval implementation, which you redefined: https://github.com/ringo/ringojs/commit/1a753a8a6dbf3a9a61a53940971d342f93d7c3d6 Note how `getCurrentWorker()` has one argument: the callback! That's missing from your re-implementation, so the "get worker from scope" path is not running.

I don't get what your code is trying to show. The example works for me; with the normal setInterval and with your JS reimplementation. If nothing I said was helpful, you might want to post a more complete example and we could work something out...

Also, I assume you are doing all that to work around the promise.wait() problem? If that is your issue, you might want to take a look at when.js or another promise implementation until we fix ours.

  simon

 simon

James Cook

unread,
May 7, 2013, 8:52:24 AM5/7/13
to rin...@googlegroups.com
Excellent, thanks. I didn't redefine setTimeout on purpose, I was using a slightly older code base. So, that change should take care of setTimeout, but I had experienced the problem in the Worker implementation where it is still using engine.getCurrentWorker() with no parameters. I had only used the setTimeout for demo purposes.



Reply all
Reply to author
Forward
0 new messages