From a35f5dff8b9f9992982ce52f011e44fb03400c4d Mon Sep 17 00:00:00 2001 From: Sam Warters <281786+samwar@users.noreply.github.com> Date: Tue, 16 Nov 2021 09:30:40 -0600 Subject: [PATCH] mc_cursor finishes returning before stopping Prior to this, `mc_cursor` processes would shut down after returning the last result, rather than after returning a final 'empty' to callers. This caused callers to try to call back for 'next()' again when cursor was already down or going down. That call is a `gen_server:call()`. In the best case, the process would already be down, and the call would result in a `noproc` exit, which this code catches and translates into a return value of 'error', instead of the correct `{}` value. In rare cases, though, due to `gen_server` code, the call would occur at the moment the process terminates, and you'll get an `exit(normal)` on the calling process instead. --- src/connection/mc_cursor.erl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/connection/mc_cursor.erl b/src/connection/mc_cursor.erl index a93eb1ab..8fecf0ab 100644 --- a/src/connection/mc_cursor.erl +++ b/src/connection/mc_cursor.erl @@ -135,22 +135,22 @@ init([Owner, Connection, Collection, Cursor, BatchSize, Batch,DB]) -> %% @hidden handle_call({next, Timeout}, _From, State) -> case next_i(State, Timeout) of - {Reply, #state{cursor = 0, batch = []} = UpdatedState} -> - {stop, normal, Reply, UpdatedState}; + {{}, UpdatedState} -> + {stop, normal, {}, UpdatedState}; {Reply, UpdatedState} -> {reply, Reply, UpdatedState} end; handle_call({rest, Limit, Timeout}, _From, State) -> case rest_i(State, Limit, Timeout) of - {Reply, #state{cursor = 0} = UpdatedState} -> - {stop, normal, Reply, UpdatedState}; + {{}, UpdatedState} -> + {stop, normal, {}, UpdatedState}; {Reply, UpdatedState} -> {reply, Reply, UpdatedState} end; handle_call({next_batch, Timeout}, _From, State = #state{batchsize = Limit}) -> case rest_i(State, Limit, Timeout) of - {Reply, #state{cursor = 0} = UpdatedState} -> - {stop, normal, Reply, UpdatedState}; + {{}, UpdatedState} -> + {stop, normal, {}, UpdatedState}; {Reply, UpdatedState} -> {reply, Reply, UpdatedState} end.