Просмотр исходного кода

Fixed of error about empty queue in case when remote connection was closed by server

Alexander Verbitsky 9 лет назад
Родитель
Сommit
c6f5863f2a
2 измененных файлов с 37 добавлено и 8 удалено
  1. 13 8
      src/epgsql_sock.erl
  2. 24 0
      test/epgsql_tests.erl

+ 13 - 8
src/epgsql_sock.erl

@@ -680,14 +680,19 @@ on_message({?READY_FOR_QUERY, <<Status:8>>}, State) ->
              end,
     {noreply, State2#state{txstatus = Status}};
 
-on_message(Error = {error, _}, State) ->
-    State2 = case command_tag(State) of
-                 C when C == squery; C == equery; C == execute_batch ->
-                     add_result(State, Error, Error);
-                 _ ->
-                     sync_required(finish(State, Error))
-             end,
-    {noreply, State2};
+on_message(Error = {error, Reason}, State) ->
+    case queue:is_empty(State#state.queue) of
+        true ->
+            {stop, {shutdown, Reason}, State};
+        false ->
+            State2 = case command_tag(State) of
+                C when C == squery; C == equery; C == execute_batch ->
+                    add_result(State, Error, Error);
+                _ ->
+                    sync_required(finish(State, Error))
+            end,
+            {noreply, State2}
+    end;
 
 %% NoticeResponse
 on_message({?NOTICE, Data}, State) ->

+ 24 - 0
test/epgsql_tests.erl

@@ -687,6 +687,30 @@ connection_closed_test(Module) ->
     end,
     flush().
 
+connection_closed_by_server_test(Module) ->
+    with_connection(Module,
+        fun(C1) ->
+            P = self(),
+            spawn_link(fun() ->
+                process_flag(trap_exit, true),
+                with_connection(Module,
+                    fun(C2) ->
+                        {ok, _, [{Pid}]} = Module:equery(C2, "select pg_backend_pid()"),
+                        % emulate of disconnection
+                        {ok, _, [{true}]} = Module:equery(C1,
+                            "select pg_terminate_backend($1)", [Pid]),
+                        receive
+                            {'EXIT', C2, {shutdown, #error{code = <<"57P01">>}}} ->
+                                P ! ok;
+                            Other ->
+                                ?debugFmt("Unexpected msg: ~p~n", [Other]),
+                                P ! error
+                        end
+                    end)
+            end),
+            receive ok -> ok end
+        end).
+
 active_connection_closed_test(Module) ->
     P = self(),
     F = fun() ->