Skip to content

Commit c8dbe23

Browse files
authored
Merge pull request #484 from rabbitmq/concurrent-directory-delete
Handle segment writer crash
2 parents cba3581 + 9ec6b5a commit c8dbe23

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

src/ra_log_segment_writer.erl

+34-27
Original file line numberDiff line numberDiff line change
@@ -198,39 +198,46 @@ handle_cast({truncate_segments, Who, {_From, _To, Name} = SegRef},
198198
%% remove all old files
199199
_ = [_ = prim_file:delete(F) || F <- Remove],
200200
%% check if the pivot has changed
201-
{ok, Seg} = ra_log_segment:open(Pivot, #{mode => read}),
202-
case ra_log_segment:segref(Seg) of
203-
SegRef ->
204-
_ = ra_log_segment:close(Seg),
205-
%% it has not changed - we can delete that too
206-
_ = prim_file:delete(Pivot),
207-
%% as we are deleting the last segment - create an empty
208-
%% successor
209-
T2 = erlang:monotonic_time(),
210-
Diff = erlang:convert_time_unit(T2 - T1, native, millisecond),
211-
?DEBUG("segment_writer in '~w': ~s for ~s took ~bms",
212-
[System, ?FUNCTION_NAME, Who, Diff]),
213-
case open_successor_segment(Seg, SegConf) of
214-
undefined ->
215-
%% directory must have been deleted after the pivot
216-
%% segment was opened
217-
{noreply, State0};
218-
Succ ->
219-
_ = ra_log_segment:close(Succ),
201+
case ra_log_segment:open(Pivot, #{mode => read}) of
202+
{ok, Seg} ->
203+
case ra_log_segment:segref(Seg) of
204+
SegRef ->
205+
_ = ra_log_segment:close(Seg),
206+
%% it has not changed - we can delete that too
207+
_ = prim_file:delete(Pivot),
208+
%% as we are deleting the last segment - create an empty
209+
%% successor
210+
T2 = erlang:monotonic_time(),
211+
Diff = erlang:convert_time_unit(T2 - T1, native,
212+
millisecond),
213+
?DEBUG("segment_writer in '~w': ~s for ~s took ~bms",
214+
[System, ?FUNCTION_NAME, Who, Diff]),
215+
case open_successor_segment(Seg, SegConf) of
216+
undefined ->
217+
%% directory must have been deleted after the pivot
218+
%% segment was opened
219+
{noreply, State0};
220+
Succ ->
221+
_ = ra_log_segment:close(Succ),
222+
{noreply, State0}
223+
end;
224+
_ ->
225+
%% the segment has changed - leave it in place
226+
T2 = erlang:monotonic_time(),
227+
Diff = erlang:convert_time_unit(T2 - T1, native,
228+
millisecond),
229+
?DEBUG("segment_writer in '~w': ~s for ~s took ~bms",
230+
[System, ?FUNCTION_NAME, Who, Diff]),
231+
_ = ra_log_segment:close(Seg),
220232
{noreply, State0}
221233
end;
222-
_ ->
223-
%% the segment has changed - leave it in place
224-
T2 = erlang:monotonic_time(),
225-
Diff = erlang:convert_time_unit(T2 - T1, native, millisecond),
226-
?DEBUG("segment_writer in '~w': ~s for ~s took ~bms",
227-
[System, ?FUNCTION_NAME, Who, Diff]),
228-
_ = ra_log_segment:close(Seg),
234+
{error, enoent} ->
235+
%% concurrent deletion of segment - assume this ra server
236+
%% is gone
229237
{noreply, State0}
230238
end
231239
end.
232240

233-
234241
handle_info(_Info, State) ->
235242
{noreply, State}.
236243

0 commit comments

Comments
 (0)