obi458 commented on issue #1182: fixed race is_idle
URL: https://github.com/apache/couchdb/pull/1182#issuecomment-368768760
 
 
   After some times on the couch and thinking about the problem i guess is_idle 
is wrong using monitored_by.
   
   I simulate scheduler(pause) always with an debug point!
   
   If i set an debug point on:
   
   Process(Fd):
   ```
   handle_info(maybe_close, File) ->
       case is_idle(File) of
           true ->
            **debug point ->**  {stop, normal, File};
           false ->
               erlang:send_after(?MONITOR_CHECK, self(), maybe_close),
               {noreply, File}
       end;
   ```
   
   and calling erlang:monitor(process, Fd) from process(OpenDb) that want to 
open Db:
   
   ```
   receive
           {'DOWN', Ref, _, _, _} ->
               {down, Db}
       after 0 ->
           {ok, Db#db{fd_monitor = Ref}}
       end.
   ```
   
   does not work, cause the Fd process lives(on my debug point)! 
   and will die shortly through {stop, normal, File}
   
   I think it is better to replace the monitor function with(and turn around 
the logic):
   
   gen_server:call(Fd,{monitored_by,OpenDb},unlimited).
   if the calling failed, we are sure the process does not exists and we 
restart to open or create the Db.
   
   In short: 
   
   1) save the OpenDb in monitored_by dict and 
   2) the couch_file monitors the OpenDb and remove OpenDb from monitored_by 
dict on 'DOWN' message.
        Therefore we have always a consistent monitored_by dict and is_idle 
will work correctly!
   
   is_idle like:
   is_idle() -> dict:size(monitored_by_dict) =:= 0.
   
   
   
   
   
   

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to