Node.js itself supports worker threads and creation of child processes. Those of you who have worked with Node.js, may be familiar with flow control libraries such as Async.js or Step.
Now since Opa runs on the Node.js stack, is there a way to use the Async.js library as a javascript module?
Are there any bindings of the Opa language to allow for either threading or some sort of async flow control? I suspect not, but I am curious as to what are the possible options of implementing threading or async flow control in Opa?
*Now I know I can shell-out and pass my work off to another script in a non-Opa language, but is that my only option?
Thanks in advance, as I am new to Opa and am trying to understand its capabilities!
Opa compiler automaticaly rewrites your code to an async Javascript code.
It's one of feature of Opa you should not take care of thread managements, it's default handled by the compiler.
Moreover Opa provides some concurrency primitive to access of its control flow.
@callcc : continuation('a) -> 'a
@spawn : 'a -> Cps.future('a)
@wait : Cps.future('a) -> 'a
Where @callcc
allows access to the current continuation. Here a example of use, built a synchronous function from an asynchronous function :
function ('a -> 'b) to_sync(('a, ('b -> void) -> void) fasync){
function (a){
@callcc(function(k){
fasync(a, Continuation.return(k, _))
})
}
}
And @spawn
to launch on an another 'thread' the computation of a value. And @wait
is used to get the spawned value. As pseudo example :
function example(){
future = @spawn(
x = fibo(30);
jlog("End of spawn computation {x}");
{result : x}
)
// ...
jlog("do something before wait")
result = @wait(future).result
jlog("the result is [resulr}")
}
//Output of example is :
// do something before wait
// the result is 832040
You can also access to scheduling primitive with the Scheduler
module
Opa has built-in support for asynchronous server calls. Unfortunately it is not well documented at the moment. But consider:
@async server function my_async_function() {
Scheduler.wait(2000);
#done = "async function done!"
}
function clicked() {
my_async_function();
#clicked = "you clicked me!"
}
function go() {
Resource.page("hello", (
<>
<p>click this button:</p>
<button onclick={function(_) { clicked() }}>
clickme</button>
<div id=#clicked/>
<div id=#done/>
</>
))
}
Uri.relative -> resource function start(uri) {
match (uri.path) {
| _ : go()
}
}
Server.start(Server.http,
{ dispatch: start }
)
(This is similar to the example from this mailing list thread, but a little simplified and updated for the current default Opa syntax.)