Handle exceptions inside sync_fold_range
Someone tried (tsk, tsk) to terminate a fold operation by throwing an exception. Now we also should handle such situations gracefully.
This commit is contained in:
parent
a911734134
commit
454a111ad7
1 changed files with 40 additions and 4 deletions
|
@ -74,18 +74,54 @@ sync_range(Ref, #btree_range{}=Range) ->
|
||||||
|
|
||||||
sync_fold_range(Ref,Fun,Acc0,Range) ->
|
sync_fold_range(Ref,Fun,Acc0,Range) ->
|
||||||
{ok, PID} = sync_range(Ref, Range),
|
{ok, PID} = sync_range(Ref, Range),
|
||||||
sync_receive_fold_range(PID,Fun,Acc0).
|
MRef = erlang:monitor(process, PID),
|
||||||
|
sync_receive_fold_range(MRef, PID,Fun,Acc0).
|
||||||
|
|
||||||
sync_receive_fold_range(PID,Fun,Acc0) ->
|
sync_receive_fold_range(MRef, PID,Fun,Acc0) ->
|
||||||
receive
|
receive
|
||||||
{fold_result, PID, K,V} ->
|
{fold_result, PID, K,V} ->
|
||||||
sync_receive_fold_range(PID, Fun, Fun(K,V,Acc0));
|
case
|
||||||
|
try
|
||||||
|
{ok, Fun(K,V,Acc0)}
|
||||||
|
catch
|
||||||
|
Class:Exception ->
|
||||||
|
lager:warning("Exception in lsm_btree fold: ~p", [Exception]),
|
||||||
|
{'EXIT', Class, Exception, erlang:get_stacktrace()}
|
||||||
|
end
|
||||||
|
of
|
||||||
|
{ok, Acc1} ->
|
||||||
|
sync_receive_fold_range(MRef, PID, Fun, Acc1);
|
||||||
|
Exit ->
|
||||||
|
%% kill the fold worker ...
|
||||||
|
erlang:exit(PID, kill),
|
||||||
|
drain_worker_and_throw(MRef,PID,Exit)
|
||||||
|
end;
|
||||||
{fold_limit, PID, _} ->
|
{fold_limit, PID, _} ->
|
||||||
|
erlang:demonitor(MRef, [flush]),
|
||||||
Acc0;
|
Acc0;
|
||||||
{fold_done, PID} ->
|
{fold_done, PID} ->
|
||||||
Acc0
|
erlang:demonitor(MRef, [flush]),
|
||||||
|
Acc0;
|
||||||
|
{'DOWN', MRef, _, _, Reason} ->
|
||||||
|
error({fold_worker_died, Reason})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
raise({'EXIT', Class, Exception, Trace}) ->
|
||||||
|
erlang:raise(Class, Exception, Trace).
|
||||||
|
|
||||||
|
drain_worker_and_throw(MRef, PID, ExitTuple) ->
|
||||||
|
receive
|
||||||
|
{fold_result, PID, _, _} ->
|
||||||
|
drain_worker_and_throw(MRef, PID, ExitTuple);
|
||||||
|
{'DOWN', MRef, _, _, _} ->
|
||||||
|
raise(ExitTuple);
|
||||||
|
{fold_limit, PID, _} ->
|
||||||
|
erlang:demonitor(MRef, [flush]),
|
||||||
|
raise(ExitTuple);
|
||||||
|
{fold_done, PID} ->
|
||||||
|
erlang:demonitor(MRef, [flush]),
|
||||||
|
raise(ExitTuple)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
async_range(Ref, #btree_range{}=Range) ->
|
async_range(Ref, #btree_range{}=Range) ->
|
||||||
|
|
Loading…
Reference in a new issue