I just tried to run a simple function in the terminal:
A1 = async:new(fun(Args) -> lists:seq(1, Args) end, 10).
It is showing the output like this: "#Ref<0.2297416181.3164864513.214889>" but when I try to run the wait function it is not working and not showing anything. I was expecting to get a result like [1,2,3,4,5,6,7,8,9,10].
Here is my full code:
-module(async).
-export([new/2, wait/1, poll/1]).
new(Fun, Arg) ->
Aid = make_ref(), % Generate a unique action ID
ComputationPid = spawn_link(fun() -> execute_computation(self(), Fun, Arg) end),
State = {ComputationPid, none},
erlang:put(Aid, State),
Aid.
execute_computation(ParentPid, Fun, Arg) ->
try
Res = Fun(Arg),
ParentPid ! {self(), {ok, Res}}
catch
throw:Ex ->
ParentPid ! {self(), {exception, Ex}}
end.
wait(Aid) ->
receive
{Aid, {ok, Res}} -> Res;
{Aid, {exception, Ex}} -> throw(Ex)
end.
poll(Aid) ->
State = erlang:get(Aid),
case State of
undefined -> nothing;
{_, none} -> nothing;
{_, Result} -> Result
end.
This line added in the terminal and it is not showing anything:
Result = async:wait(A1).
The main problem is you're mixing up references and pids. In your
execute_computation/3function, you send messages with the pid as the first element of the tuple:But in your
wait/1function, you're attempting to receive tuples with a reference as the first element:Another problem is that when you spawn the
execute_computation/3call, you're trying to pass the parent pid but theself()call within thefunis the pid of the spawned process, not the parent.To fix it, first, change how you spawn the call to
execute_computation/3by passing the parent pid and also passing the reference:Next, fix the
execute_computationfunction to take 4 arguments and to include the reference in the sent tuple:And finally, fix
wait/1to receive the correct tuple:Note that you don't appear to be using the pid of the
execute_computation/3process that's passed in the tuple, so you might consider dropping it.With these changes, things work as expected: