Skip to content

Instantly share code, notes, and snippets.

@kaeluka
Last active August 29, 2015 14:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kaeluka/f09b4eb7be09d9fa243f to your computer and use it in GitHub Desktop.
Save kaeluka/f09b4eb7be09d9fa243f to your computer and use it in GitHub Desktop.
Futures in erlang
-module(future).
-export([async/1, fulfill/2, block/1, test/0]).
async(Fun) ->
F = mk(),
spawn(fun() ->
fulfill(F, Fun()) end),
F.
fulfill(F, Val) ->
F ! {fulfill, Val},
ok.
block(F) ->
R = make_ref(),
F ! {get, self(), R},
receive
{reply, Val, R} ->
exit(F, kill),
Val
end.
await(Waiting) ->
receive
{fulfill, Val} ->
[notify(W, Val, Ref) || {get, W, Ref} <- Waiting],
serve(Val);
{get, W, Ref} ->
await([{get, W, Ref} | Waiting])
end.
notify(W, Val, Ref) ->
W ! {reply, Val, Ref},
ok.
serve(Val) ->
receive
{get, W, Ref} ->
notify(W, Val, Ref),
serve(Val)
end.
mk() ->
spawn(fun() -> await([]) end).
test() ->
F = async(fun() ->
io:format("working hard...~n"),
receive after 2000 -> ok end,
io:format("got it!~n"),
10
end),
spawn(fun() ->
io:format("waiting..~n"),
io:format("received result: ~w~n", [block(F)]),
io:format("received result: ~w~n", [block(F)])
end),
ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment