diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e65d8456..660ad6ce17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - [#1696](https://github.com/poanetwork/blockscout/pull/1696) - full-text search by tokens - [#1742](https://github.com/poanetwork/blockscout/pull/1742) - Support RSK - [#1777](https://github.com/poanetwork/blockscout/pull/1777) - show ERC-20 token transfer info on transaction page +- [#1770](https://github.com/poanetwork/blockscout/pull/1770) - set a websocket keepalive from config ### Fixes diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/web_socket/web_socket_client.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/web_socket/web_socket_client.ex index 8878253793..e4e6d2ac8c 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/web_socket/web_socket_client.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/web_socket/web_socket_client.ex @@ -50,7 +50,9 @@ defmodule EthereumJSONRPC.WebSocket.WebSocketClient do @impl WebSocket # only allow secure WSS - def start_link(["wss://" <> _ = url, gen_fsm_options]) when is_list(gen_fsm_options) do + def start_link(["wss://" <> _ = url, websocket_opts, gen_fsm_options]) when is_list(gen_fsm_options) do + keepalive = websocket_opts[:keepalive] + fsm_name = case Keyword.fetch(gen_fsm_options, :name) do {:ok, name} when is_atom(name) -> {:local, name} @@ -68,6 +70,7 @@ defmodule EthereumJSONRPC.WebSocket.WebSocketClient do __MODULE__, url, ssl_verify: :verify_peer, + keepalive: keepalive, socket_opts: [ cacerts: :certifi.cacerts(), depth: 99, @@ -78,7 +81,9 @@ defmodule EthereumJSONRPC.WebSocket.WebSocketClient do ) end - def start_link(["ws://" <> _ = url, gen_fsm_options]) when is_list(gen_fsm_options) do + def start_link(["ws://" <> _ = url, websocket_opts, gen_fsm_options]) when is_list(gen_fsm_options) do + keepalive = websocket_opts[:keepalive] + fsm_name = case Keyword.fetch(gen_fsm_options, :name) do {:ok, name} when is_atom(name) -> {:local, name} @@ -90,7 +95,7 @@ defmodule EthereumJSONRPC.WebSocket.WebSocketClient do url, __MODULE__, url, - [] + keepalive: keepalive ) end diff --git a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/web_socket/web_socket_client_test.exs b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/web_socket/web_socket_client_test.exs index 986eeb362a..06a9316e52 100644 --- a/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/web_socket/web_socket_client_test.exs +++ b/apps/ethereum_jsonrpc/test/ethereum_jsonrpc/web_socket/web_socket_client_test.exs @@ -89,7 +89,7 @@ defmodule EthereumJSONRPC.WebSocket.WebSocketClientTest do port = :ranch.get_port(EthereumJSONRPC.WebSocket.Cowboy) - pid = start_supervised!({WebSocketClient, ["ws://localhost:#{port}/websocket", []]}) + pid = start_supervised!({WebSocketClient, ["ws://localhost:#{port}/websocket", [keepalive: :timer.hours(1)], []]}) %{pid: pid, port: port} end diff --git a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/geth.ex b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/geth.ex index f808c24900..957d31e7a9 100644 --- a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/geth.ex +++ b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/geth.ex @@ -8,7 +8,7 @@ defmodule EthereumJSONRPC.WebSocket.Case.Geth do def setup do url = "wss://mainnet.infura.io/ws/8lTvJTKmHPCHazkneJsY" web_socket_module = EthereumJSONRPC.WebSocket.WebSocketClient - web_socket = start_supervised!({web_socket_module, [url, []]}) + web_socket = start_supervised!({web_socket_module, [url, [keepalive: :timer.minutes(10)], []]}) %{ block_interval: 25_000, diff --git a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/mox.ex b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/mox.ex index 94d0d00b61..57546f49f1 100644 --- a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/mox.ex +++ b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/mox.ex @@ -19,7 +19,7 @@ defmodule EthereumJSONRPC.WebSocket.Case.Mox do Supervisor.child_spec( %{ id: web_socket_module, - start: {web_socket_module, :start_link, arguments} + start: {web_socket_module, :start_link, [arguments]} }, [] ) @@ -29,7 +29,7 @@ defmodule EthereumJSONRPC.WebSocket.Case.Mox do end) url = "wss://example.com/ws" - web_socket = start_supervised!({web_socket_module, [url]}) + web_socket = start_supervised!({web_socket_module, [url, [keepalive: :timer.minutes(10)]]}) %{ block_interval: @block_interval, diff --git a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex index e636ea2520..d84469aaf9 100644 --- a/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex +++ b/apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/web_socket/case/parity.ex @@ -8,7 +8,7 @@ defmodule EthereumJSONRPC.WebSocket.Case.Parity do def setup do url = "ws://3.85.253.242:8546" web_socket_module = EthereumJSONRPC.WebSocket.WebSocketClient - web_socket = start_supervised!({web_socket_module, [url, []]}) + web_socket = start_supervised!({web_socket_module, [url, [keepalive: :timer.minutes(10)], []]}) %{ block_interval: 5_000, diff --git a/apps/indexer/README.md b/apps/indexer/README.md index 81b45300ef..ceb4ce9d0f 100644 --- a/apps/indexer/README.md +++ b/apps/indexer/README.md @@ -104,6 +104,10 @@ Memory usage is checked once per minute. If the soft-limit is reached, the shri If all queues are at their minimum size, then no more memory can be reclaimed and an error will be logged. +## Websocket Keepalive + +This defaults to 150 seconds, but it can be set via adding a configuration to `subscribe_named_arguments` in the appropriate config file (indexer/config//.exs) called `:keep_alive`. The value is an integer representing milliseconds. + ## Testing ### Parity diff --git a/apps/indexer/lib/indexer/block/realtime/supervisor.ex b/apps/indexer/lib/indexer/block/realtime/supervisor.ex index 233e616b81..9a7f2b29c8 100644 --- a/apps/indexer/lib/indexer/block/realtime/supervisor.ex +++ b/apps/indexer/lib/indexer/block/realtime/supervisor.ex @@ -22,12 +22,14 @@ defmodule Indexer.Block.Realtime.Supervisor do transport_options = %EthereumJSONRPC.WebSocket{transport_options | web_socket_options: web_socket_options} %EthereumJSONRPC.WebSocket{url: url, web_socket: web_socket_module} = transport_options + keepalive = Keyword.get(subscribe_named_arguments, :keep_alive, :timer.seconds(150)) + block_fetcher_subscribe_named_arguments = put_in(subscribe_named_arguments[:transport_options], transport_options) [ {Task.Supervisor, name: Indexer.Block.Realtime.TaskSupervisor}, - {web_socket_module, [url, [name: web_socket]]}, + {web_socket_module, [url, [keepalive: keepalive], [name: web_socket]]}, {Indexer.Block.Realtime.Fetcher, [ %{block_fetcher: block_fetcher, subscribe_named_arguments: block_fetcher_subscribe_named_arguments},