Skip to content
This repository has been archived by the owner on May 25, 2021. It is now read-only.

Commit

Permalink
Make httpc connection closing asynchronous (#47)
Browse files Browse the repository at this point in the history
httpc pool's terminate/2 can block up to 5 seconds in case when ssl sockets
are used. Previously this was not an issue as replication jobs would run until
completion and only exit once. With the scheduler, replication jobs are stopped
regularly during rescheduling. So terminate/2 could be called `max_churn` number
of times in a row during each reschedule cycle. This could lead to scheduler
gen_server being blocked for up to 100 seconds at a time.

To fix, unlink the connection and call stop in a separate process. This way,
socket will get a chance to be closed properly, but if it doesn't, ibrowse
client will kill it (this ensures connection processes won't leak).
  • Loading branch information
nickva committed Aug 3, 2016
1 parent 7a08005 commit 58d2ade
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/couch_replicator_httpc_pool.erl
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,15 @@ code_change(_OldVsn, #state{}=State, _Extra) ->
{ok, State}.


terminate(_Reason, State) ->
lists:foreach(fun ibrowse_http_client:stop/1, State#state.free),
lists:foreach(fun ibrowse_http_client:stop/1, State#state.busy).
terminate(_Reason, #state{free=Free, busy=Busy}) ->
% ibrowse_http_client stop can take up to 5 seconds to close an ssl socket
% (if it times out after five, it brutally kills process)
[begin
unlink(Con),
spawn(ibrowse_http_client, stop, [Con])
end || Con <- Free ++ Busy],
ok.


monitor_client(Callers, Worker, {ClientPid, _}) ->
[{Worker, erlang:monitor(process, ClientPid)} | Callers].
Expand Down

0 comments on commit 58d2ade

Please sign in to comment.