[erlang-questions] Futures/promises and ability to "call" abstract modules

Gleb Peregud <>
Tue Nov 20 17:55:41 CET 2012


Yes, it is very handy :) Thanks!

Actually I've used it to create basic implementation of GC-able processes here:

https://github.com/gleber/gcproc

On Tue, Nov 20, 2012 at 5:16 PM, Tony Rogvall <> wrote:
>
> On 20 nov 2012, at 16:20, Gleb Peregud <> wrote:
>
> This is yet to be implemented. The idea is to rely on already existing
> implementation of NIF resources - this implies that a user of the
> library would have to always store Pid of garbage collectable process
> (let's call it gcproc) along with that resource in his heap, for
> example as {'gcproc', pid(), resource()} and use special API to do
> sending, killing, linking, monitoring, etc.
>
> Since the resource associated with the process is always stored in
> heap of the process, the resource will not get garbage collected until
> no heap references it. This way we tie together process and resource
> lifetime. And since NIF resources can have a destructor in C which is
> called upon resource is garbage collected, we can make use of it to
> inform gcproc to terminate.
>
> As Patrik pointed out it is not as trivial as it sounds, but still possible.
>
> Maybe git://github.com/tonyrog/resource.git could come in handy.
>
> /Tony
>
> On Tue, Nov 20, 2012 at 3:34 PM, David Mercer <> wrote:
>
> How does that spawned process get garbage collected?
>
> Cheers,
>
> DBM
>
>
> -----Original Message-----
> From:  [mailto:erlang-questions-
> ] On Behalf Of Dmitry Belyaev
> Sent: Monday, November 19, 2012 21:48
> To: Gleb Peregud
> Cc: Erlang
> Subject: Re: [erlang-questions] Futures/promises and ability to "call"
> abstract modules
>
> Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:2:2] [async-threads:0]
> [hipe] [kernel-poll:false]
>
> Eshell V5.9.1  (abort with ^G)
> 1> F = (fun() -> FM = fun(M, V) -> receive {value, Value} -> M(M, Value);
> {get, P} -> P ! V, M(M, V) end end, P = spawn(fun() -> FM(FM, undefined)
> end), fun() -> P ! {get, self()}, receive V -> V end end end)().
> #Fun<erl_eval.20.82930912>
> 2> F().
> undefined
> 3> element(2,lists:keyfind('P', 1,
> lists:flatten(element(2,erlang:fun_info(F, env))))) ! {value, 10}.
> {value,10}
> 4> F().
> 10
> 5>
>
> --
> Dmitry Belyaev
>
> On 19.11.2012, at 18:05, Gleb Peregud wrote:
>
> Then I wouldn't be able to set future's value after it being defined.
> Like in this example:
>
> 7> F = future:new().
> {future,<0.47.0>,#Ref<0.0.0.27235>,undefined}
> 8> spawn(fun() -> timer:sleep(10000), F:set(42) end).
> <0.49.0>
> 9> F:get().
> 42
>
> Without this ability such futures are useless with request-reply
>
> pattern:
>
> 1) Client sends request
> 2) Server creates a future and sends it back to client
> 3) Client does it's work with the value of the future (without
> bothering the fact that value may become available in uncertain
> future)
> 4) Server finishes computations and sets future's value
>
>
> On Mon, Nov 19, 2012 at 3:01 PM, Robert Virding
> <> wrote:
>
> Wouldn't it be easier if future:new just returned a fun? Then you could
>
> do F() without any changes?
>
>
> Robert
>
> ----- Original Message -----
>
> From: "Gleb Peregud" <>
> To: "Vlad Dumitrescu" <>
> Cc: "Erlang" <>
> Sent: Monday, 19 November, 2012 2:18:11 PM
> Subject: Re: [erlang-questions] Futures/promises and ability to
> "call" abstract modules
>
> With the these changes [1] the following code works as intended:
>
> 7> F = future:new(fun() -> timer:sleep(5000), 42 end).
> {future,<0.44.0>,#Ref<0.0.0.71>,undefined}
> 8> F().
> 42
>
> Aside from a problem where it improperly reports arity in case of
> undefined function:
>
> 9> F(1,2,3).
> ** exception error: undefined function future:call/3
>
> 1: https://github.com/gleber/otp/compare/call-abstract-module
>
> On Mon, Nov 19, 2012 at 11:48 AM, Gleb Peregud <>
> wrote:
>
> Sverker Eriksson wrote the following in [1]:
>
> But even if the resource terms look alike, they are unique and
> there is no bug leaking NIF resources (that I know of). A resource
> is released (and destructor called) when the last reference is
> garbage collected.
> The shell can fool you however, as it keeps a command history that
> can retain terms even though you think the variables are
> forgotten.
> Test NIF
> resource cleanup by running a test module and call
> erlang:garbage_collect to force destructors to be called.
>
>
> This seems to mean that they are "shared" and garbage collected
> just once.
>
> 1:
> http://erlang.org/pipermail/erlang-questions/2011-January/055524.ht
> ml
>
> On Mon, Nov 19, 2012 at 11:46 AM, Vlad Dumitrescu
> <> wrote:
>
> I have no idea, that's why I asked :-) /Vlad
>
>
> On Mon, Nov 19, 2012 at 11:44 AM, Gleb Peregud
> <> wrote:
>
>
> I assumed that NIF-generated resources are shared between
> processes (the same way as large binaries are), and I haven't
> done any tests on this. Are you sure it is garbate collected
> multiple times (once per referencing process)?
>
>
>
> On Mon, Nov 19, 2012 at 11:41 AM, Vlad Dumitrescu
> <>
> wrote:
>
>
> Hi Gleb,
>
> just a quick observation about garbage collecting futures: would
> the NIF-generated resource keep track of usage across processes?
> I fI send a future as a message, it may be referenced by
> multiple processes which have their own heap and garbage
> collection...
>
> regards,
> Vlad
>
>
> On Mon, Nov 19, 2012 at 11:32 AM, Gleb Peregud
> <>
> wrote:
>
>
> Hello
>
> Last evening I was trying to implement futures/promise
> mechanism in Erlang (mostly for fun, since I am still unsure if
> it is useful). I got inspired with the presentation [1], which
> mentioned using futures as a foundation of building services,
> where things like timeouts, tracing, authentication, etc. is
> built by composing futures (see slide 41).
>
> Do you think that such composition of futures could be useful
> as a tool to improve code reuse of communication patterns in
> Erlang (as described in the presentation)?
>
> I've implemented futures using processes and message passing
> and stumbled upon two issues:
> 1) garbage collection of futures
> 2) slightly too much code when using them
>
> Example of the first problem is here:
>
> 1> F = future:new(fun() -> timer:sleep(10000), 10 end).
> {future,<0.36.0>,#Ref<0.0.0.1736>,undefined}
> 2> F:get(). %% it hangs for 10 seconds
> 10
>
> Since future F is represented as a process <0.36.0> it will
> stay running forever till it's timed out (which is not a good
> solution, since someone may still have a reference to this
> future) or F:done() manually called.
>
> My idea is to insert into 'future' tuple a NIF-generated
> resource, which will have a destructor attached (called upon
> garbage collection of the
> resource) which will call F:done(). Will it work?
>
> The second issue is illustrated here:
>
> 7> F = future:new().
> {future,<0.47.0>,#Ref<0.0.0.27235>,undefined}
> 8> spawn(fun() -> timer:sleep(10000), F:set(42) end).
> <0.49.0>
> 9> F:get().
> 42
>
> In ideal world it should be enough to just write "F" (without
> :get()) to
> fetch future's value, but it seems too far fetched for Erlang.
> Slightly
> better solution would be to allow calling future with "F()".
>
> This can be done by extending concept of "abstract modules"
> with
> "default call". Currently abstract modules allow the following:
>
> {future, Pid, Ref, undefined}:get() which is translated to
> future:get({future, Pid, Ref, undefined})
>
> With a simple change in beam_emu.c in call_fun function (which
> would replace obsolete fun tuples) we can allow for the
> following:
>
> {future, Pid, Ref, undefined}() which COULD be translated to
> future:call({future, Pid, Ref, undefined})
>
> hence allowing to use just "F()" to read a value of the future.
> This
> will also extend "metaprogramming" capabilities of Erlang for
> some other quirky use, which may or may not be a Good
> Thing(tm).
>
> Thoughts?
>
> Cheers,
> Gleb Peregud
>
> 1: http://monkey.org/~marius/talks/twittersystems/
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
> "Installing applications can lead to corruption over time. Applications
> gradually write over each other's libraries, partial upgrades occur, user
> and system errors happen, and minute changes may be unnoticeable and
> difficult to fix"
>
>
>



More information about the erlang-questions mailing list