Search code examples
concurrencyerlangspawnerlang-otp

How to spawn processes in Erlang more efficiently?


I have these two functions

check_requests(Timestamp,Plan,AddInfo)->
    {Day,_Month,_Year,Hour,Minute,Second,Micro} = Timestamp,
    ExpiredRequests = lists:filter(fun(Elem) -> 
                               {_ID,Time,_Key,_Action} = Elem,
                               Time < {Day,Hour,Minute,Second,Micro}
                               end, Plan),
    NewPlan = Plan -- ExpiredRequests,
    make_requests(ExpiredRequests,AddInfo),
    NewPlan.

make_requests([],_)->ok;
make_requests([ExpiredRequest|Rest],AddInf)->
    {_ID,_Time,Key,Action} = ExpiredRequest,
    spawn(?MODULE,request,[AddInf,Action,Key]),
    make_requests(Rest,AddInf).

The main idea is that I have plan where each request is given a time when it expires and should be executed. Upon expiry, I want to execute the request concurrently with other requests that may expire in time so I spawn the request function with new process. Now, If I have millions of requests, I will have millions of processes and I assume that is not desired. The request execution may last maximally one minute. I would like to know what happens to the process when the function I spawned is finished. Is it killed? or does it still exists and should be garbage collected? I really need requests to be concurrent and have no idea how else could I implement it. Also is there some OTP behaviour that could be helpful in this case? I have not studied OTP yet, I'm somewhere in the middle of the whole Erlang framework.


Solution

  • The spawned process exits when the function finishes running. Nothing needs to be garbage collected; the entire process heap is deallocated. (Except for binaries over 64 bytes, which are kept in a shared heap.)

    A note about your code: if you need to separate a long list into the elements that satisfy a certain predicate and those that don't, it's more efficient to use lists:partition/2 than using lists:filter and then --. The former runs in linear time to the length of the list, while -- can run in quadratic time if you're unlucky.