CAF Wasm support

41 views
Skip to first unread message

Dulaj Viduranga

unread,
Jun 14, 2019, 5:11:40 AM6/14/19
to actor-framework
Hello,
I would like to know if there is a way to configure CAF to run synchronously on just a single thread (only the main thread). 
The requirement is that I have a system that is developed to support Desktop, Android (JNI), and Web (Wasm). The core code base is same for all platforms and separate wrappers are used to expose APIs. I decided to integrate an actor framework to the system and CAF is the obvious choice. I was able to do a test run on Android and it works perfectly.
However, due to the reason that the browsers have disabled multithreading support for wasm now, I cannot build CAF with emscripten for wasm. If there is a way not to use the default actor_system and do a synchronous message passing in the same thread, I would be able to use the same code base for all the platforms.
I would be thankful if anyone can provide some insights on how to tackle this problem. 

Thanks.

Dominik Charousset

unread,
Jun 19, 2019, 3:27:27 AM6/19/19
to actor-f...@googlegroups.com
Hi,

> I would like to know if there is a way to configure CAF to run synchronously on just a single thread (only the main thread).

The short answer is no. But there’s also a long answer. it’s not something I would usually recommend, since this comes with a couple of caveats.

There is a scheduler in CAF that does not spin up any threads. It’s called `test_coordinator` since we use it for writing deterministic unit tests.

You can configure CAF to use that instead of the work-stealing scheduler by setting the config parameter `cfg.set("scheduler.policy", caf::atom("testing"));`.

After that, you’ll notice that your application won’t do anything since you have to trigger everything manually now.

For that, you’ll need to get a reference to the scheduler: `auto& sched = dynamic_cast<caf::scheduler::test_coordinator&>(sys.scheduler());`.

The simplest way to just run everything is to call `sched.run()`, but you’ll notice that no timeout gets ever triggered. If you’re using `after()`, `delayed_send()`, requests with timeouts or anything like that, it’s going to get complicated. The test scheduler comes with a fake clock, so you’ll also have to manage time manually. If you’re using CAF’s new streams, this will also mess up credit management.

As long as you’re using a small subset of CAF and only rely on asynchronous messages, this might be feasible. However, anything that touches the clock is going to be tricky.


Hope I could provide at least some insights,
Dominik

Dulaj Viduranga

unread,
Jun 19, 2019, 5:39:23 AM6/19/19
to actor-framework
This is very helpful. I will test this out and post the results here for reference.

Thank you very much Dominik.

Dulaj Viduranga

unread,
Aug 13, 2019, 2:08:04 AM8/13/19
to actor-framework
This was fairly straight forward. The only thing is you have to disable all the additional threads from running.

    cfg.set("scheduler.policy", caf::atom("testing"));
    cfg.set("logger.verbosity", caf::atom("quite"));

did the trick. After that, you can get the scheduler as Dominik explained and use scheduler.run() after each send and receive to propagate the messages manually.
Reply all
Reply to author
Forward
0 new messages