Futures and Promises in Erlang

2019-06-26 18:54发布

问题:

Does Erlang has equivalents for Future and Promises? Or since future and promises are solving a problem that doesn't exist in Erlang systems (synchronisation orchestrating for example), and hence we don't need them in Erlang.

If I want the semantics of futures and promises in Erlang, they could be emulated via Erlang processes/actors?

回答1:

You could easily implement a future in Erlang like this:

F = fun() -> fancy_function() end,

% fancy code

Pid = self(),
Other = spawn(fun() -> X = F(), Pid ! {future, self(), X} end).

% more fancy code

Value = receive {future, Other, Val} -> Val end.

Having this functionality in a module and building chains from it should be easy too, but to be honest I never actually missed something like this. You are more flexible if you just freely send messages around.



回答2:

The RPC module contains the rpc:async_call/4 function that does what you need. It will run a computation anywhere in a cluster (including on node(), the local node), and allow to have the result waited on with rpc:yield/1:

1> MaxTime = rpc:async_call(node(), timer, sleep, [30000]).
<0.48.0>
2> lists:sort([a,c,b]).
[a,b,c]
3> rpc:yield(MaxTime).
... [long wait] ...
ok

You can also poll in non-blocking ways by using rpc:nb_yield/1, or for a limited number of milliseconds with rpc:nb_yield/2:

4> Key2 = rpc:async_call(node(), timer, sleep, [30000]).
<0.52.0>
5> rpc:nb_yield(Key2).
timeout
6> rpc:nb_yield(Key2).
timeout
7> rpc:nb_yield(Key2).
timeout
8> rpc:nb_yield(Key2, 1000).
timeout
9> rpc:nb_yield(Key2, 100000).
... [long wait] ...
{value,ok}

That's all in the standard library and ready to be used.