Mapping processes

martin j logan <>
Tue Dec 17 23:26:28 CET 2002


Eduardo, 
   When I first started using erlang I also had this idea.  I went so
far as to implement it. I spent about an hour trying to figure out what
clever construct I had come up with in order to fool the garbage
collector so completely and cause such a nasty "memory leak". The thing
is that the first argument to register must be an atom so you must
convert reqID to an atom. I found out after a bit of research that atoms
are not garbage collected, they are stored in a table for the life of
the system. So in the interest of helping a fellow erlanger avoid such
folly as I engaged in let me say that you should not ever dynamically
create atoms in any situation that is not garaunteed to be finite. I
typically use an ets table, loop data/dict, or some such to store
mappings. This is coupled with some facility to remove the processes
when they die. In this manner you can nicely achieve the same
functionality.

Cheers,
Martin 

On Tue, 2002-12-17 at 13:50, Vladimir Sekissov wrote:
> Good day,
> 
> eduardo> What do you think about using register(reqId, PID) and
> eduardo> whereis(reqId) to  
> eduardo> retrieve the PID so to send the response, in an async. way,
> eduardo> to the calling process. 
> 
> I think you could easily exceed the atoms table limit on long living
> system. Using simple dictionary of {callerPid, reqId} and trapping
> exit messages from callers to delete records from dictionary would be
> better solution. May be like this or as gen_server:
> 
> create_dict() ->
>   spawn_link(fun dict_srv/0).
> 
> remove_dict(DPid) ->
>   DPid ! {self(), stop},
>   receive
>     {DPid, stopped} ->
>       ok
>   end.
> 
> dict_add(DPid, Pid, Reg) ->
>   DPid ! {self(), add, {Pid, Reg}}.
> 
> dict_get(DPid, Reg) ->
>   DPid ! {self(), get, Reg},
>   receive
>     {DPid, {value, {Pid, _}}} ->
>       Pid;
>     {DPid, false} ->
>       undefined 
>   end.
>     
> dict_srv() ->
>   process_flag(trap_exit, true),
>   dict_loop([]).
> 
> dict_loop(Dict) ->
>   receive
>     {_From, add, V={Pid, Reg}} ->
>       link(Pid),
>       dict_loop([V|Dict]);
>     {From, get, Reg} ->
>       From ! {self(), lists:keysearch(Reg, 2, Dict)},
>       dict_loop(Dict);
>     {'EXIT', Pid, Reson} ->
>       case lists:keymember(Pid, 1, Dict) of
> 	true ->
> 	  dict_loop(lists:keydelete(Pid, 1, Dict));
> 	false ->
> 	  exit(Reson)
>       end;
>     {From, stop} ->
>       From ! {self(), stopped},
>       ok
>   end.
> 
> Best Regards,
> Vladimir Sekissov
> 
> eduardo> 
> eduardo> I'm thinking how to map processes with request Id so to manage
> eduardo> callbacks when using ports.
> eduardo> What do you think about using register(reqId, PID) and whereis(reqId) to 
> eduardo> retrieve the PID so to send the response, in an async. way, to the calling process.
> eduardo> 
> eduardo> 
> eduardo> 
> eduardo> Thanks,
> eduardo> Eduardo Figoli
> eduardo> INSwitch Solutions
> eduardo> 
> eduardo> 
> eduardo> 
> eduardo> 





More information about the erlang-questions mailing list