@@ -72,6 +72,29 @@ ForwardCache::get(boost::json::object const& request) const
7272 return {latestForwarded_.at (*command)};
7373}
7474
75+ static boost::beast::websocket::stream_base::timeout
76+ make_TimeoutOption ()
77+ {
78+ // See #289 for details.
79+ // TODO: investigate the issue and find if there is a solution other than
80+ // introducing artificial timeouts.
81+ if (true )
82+ {
83+ // The only difference between this and the suggested client role is
84+ // that idle_timeout is set to 20 instead of none()
85+ auto opt = boost::beast::websocket::stream_base::timeout{};
86+ opt.handshake_timeout = std::chrono::seconds (30 );
87+ opt.idle_timeout = std::chrono::seconds (20 );
88+ opt.keep_alive_pings = false ;
89+ return opt;
90+ }
91+ else
92+ {
93+ return boost::beast::websocket::stream_base::timeout::suggested (
94+ boost::beast::role_type::client);
95+ }
96+ }
97+
7598// Create ETL source without grpc endpoint
7699// Fetch ledger and load initial ledger will fail for this source
77100// Primarly used in read-only mode, to monitor when ledgers are validated
@@ -200,11 +223,21 @@ PlainETLSource::close(bool startAgain)
200223 }
201224 closing_ = false ;
202225 if (startAgain)
226+ {
227+ ws_ = std::make_unique<boost::beast::websocket::stream<
228+ boost::beast::tcp_stream>>(
229+ boost::asio::make_strand (ioc_));
230+
203231 run ();
232+ }
204233 });
205234 }
206235 else if (startAgain)
207236 {
237+ ws_ = std::make_unique<
238+ boost::beast::websocket::stream<boost::beast::tcp_stream>>(
239+ boost::asio::make_strand (ioc_));
240+
208241 run ();
209242 }
210243 });
@@ -299,10 +332,8 @@ PlainETLSource::onConnect(
299332 // own timeout system
300333 boost::beast::get_lowest_layer (derived ().ws ()).expires_never ();
301334
302- // Set suggested timeout settings for the websocket
303- derived ().ws ().set_option (
304- boost::beast::websocket::stream_base::timeout::suggested (
305- boost::beast::role_type::client));
335+ // Set a desired timeout for the websocket stream
336+ derived ().ws ().set_option (make_TimeoutOption ());
306337
307338 // Set a decorator to change the User-Agent of the handshake
308339 derived ().ws ().set_option (
@@ -343,10 +374,8 @@ SslETLSource::onConnect(
343374 // own timeout system
344375 boost::beast::get_lowest_layer (derived ().ws ()).expires_never ();
345376
346- // Set suggested timeout settings for the websocket
347- derived ().ws ().set_option (
348- boost::beast::websocket::stream_base::timeout::suggested (
349- boost::beast::role_type::client));
377+ // Set a desired timeout for the websocket stream
378+ derived ().ws ().set_option (make_TimeoutOption ());
350379
351380 // Set a decorator to change the User-Agent of the handshake
352381 derived ().ws ().set_option (
@@ -924,8 +953,6 @@ ETLSourceImpl<Derived>::fetchLedger(
924953 " correctly on the ETL source. source = "
925954 << toString () << " status = " << status.error_message ();
926955 }
927- // BOOST_LOG_TRIVIAL(debug)
928- // << __func__ << " Message size = " << response.ByteSizeLong();
929956 return {status, std::move (response)};
930957}
931958
0 commit comments