gremlex icon indicating copy to clipboard operation
gremlex copied to clipboard

Gracefully Handle Websocket Closed Connections

Open barakyo opened this issue 5 years ago • 2 comments

Hi friends :wave: ,

I'm working on helping someone debug an issue where Gremlex errors on really long queries. I believe it may be due to server configuration. In the mean time I noticed that we were missing a case in our Socket.Web.recv! where it could return a close tuple. This is when the websocket receiver closes the connection. The socket library will catch 1006 error codes and return them as a close tuple with :abormal.

This PR addresses that and will returns an error tuple rather than raising an error.

Thanks!

barakyo avatar May 22 '19 02:05 barakyo

@barakyo Can you still see the output on Travis CI You got an error Gremlex.ClientTests

  • test query/1 that it can return a successful query (207.3ms)
  • test query/1 allows you to create a new vertex without a property (41.4ms)
  • test query/1 returns an error tuple for long queries (10.1ms)
  • test query/1 allows you to create a relationship between two vertices 03:15:37.499 [error] GenServer #PID<0.259.0> terminating ** (Socket.Error) TLS connection is closed (socket) lib/socket/web.ex:840: Socket.Web.send!/3 (gremlex) lib/gremlex/client.ex:93: Gremlex.Client.handle_call/3 (stdlib) gen_server.erl:661: :gen_server.try_handle_call/4 (stdlib) gen_server.erl:690: :gen_server.handle_msg/6 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message (from #PID<0.444.0>): {:query, "{"requestId":"c0a8f9dc-3013-4396-bb64-1e4dc618a924","processor":"","op":"eval","args":{"language":"gremlin-groovy","gremlin":"g.addV('foo').property('name', 'bar')"}}", 5000} State: %{socket: %Socket.Web{extensions: nil, headers: %{}, key: "Zm9yayB0aGUgZG9uZ2xlcw==", mask: true, origin: nil, path: "/gremlin", protocols: nil, socket: #Port<0.57>, version: 13}} Client #PID<0.444.0> is alive (stdlib) gen.erl:169: :gen.do_call/4 (elixir) lib/gen_server.ex:986: GenServer.call/3 (poolboy) /app/deps/poolboy/src/poolboy.erl:84: :poolboy.transaction/3 test/client_test.exs:66: Gremlex.ClientTests."test query/1 allows you to create a relationship between two vertices"/1 (ex_unit) lib/ex_unit/runner.ex:355: ExUnit.Runner.exec_test/1 (stdlib) timer.erl:166: :timer.tc/1 (ex_unit) lib/ex_unit/runner.ex:306: anonymous fn/4 in ExUnit.Runner.spawn_test_monitor/4
  • test query/1 allows you to create a relationship between two vertices (52.6ms) 03:15:37.509 [debug] Delay: 0
  1. test query/1 allows you to create a relationship between two vertices (Gremlex.ClientTests) test/client_test.exs:65 ** (exit) exited in: GenServer.call(#PID<0.259.0>, {:query, "{"requestId":"c0a8f9dc-3013-4396-bb64-1e4dc618a924","processor":"","op":"eval","args":{"language":"gremlin-groovy","gremlin":"g.addV('foo').property('name', 'bar')"}}", 5000}, 5000) ** (EXIT) an exception was raised: ** (Socket.Error) TLS connection is closed (socket) lib/socket/web.ex:840: Socket.Web.send!/3 (gremlex) lib/gremlex/client.ex:93: Gremlex.Client.handle_call/3 (stdlib) gen_server.erl:661: :gen_server.try_handle_call/4 (stdlib) gen_server.erl:690: :gen_server.handle_msg/6 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 code: {_, [s]} = g() |> add_v("foo") |> property("name", "bar") |> query()

kevmojay avatar May 22 '19 17:05 kevmojay

@kevmojay @barakyo Yeah, that's because we don't reconnect or remove the worker with closed connection from the pool (Previously it crashed and poolboy removed it). This leads to next request getting failed. I've addressed that here: https://github.com/Revmaker/gremlex/pull/81 But I want to mock the Socket.Web somehow so that we don't rely on that huge query in tests. Didn't find a way to mock it yet though.

nimf avatar May 27 '19 15:05 nimf