2424#include " rpc/JS.hpp"
2525#include " util/Retry.hpp"
2626#include " util/log/Logger.hpp"
27+ #include " util/prometheus/Label.hpp"
28+ #include " util/prometheus/Prometheus.hpp"
2729#include " util/requests/Types.hpp"
2830
2931#include < boost/algorithm/string/classification.hpp>
@@ -66,22 +68,28 @@ SubscriptionSource::SubscriptionSource(
6668 OnConnectHook onConnect,
6769 OnDisconnectHook onDisconnect,
6870 OnLedgerClosedHook onLedgerClosed,
69- std::chrono::steady_clock::duration const connectionTimeout ,
71+ std::chrono::steady_clock::duration const wsTimeout ,
7072 std::chrono::steady_clock::duration const retryDelay
7173)
7274 : log_(fmt::format(" SubscriptionSource[{}:{}]" , ip, wsPort))
7375 , wsConnectionBuilder_(ip, wsPort)
7476 , validatedLedgers_(std::move(validatedLedgers))
7577 , subscriptions_(std::move(subscriptions))
7678 , strand_(boost::asio::make_strand(ioContext))
79+ , wsTimeout_(wsTimeout)
7780 , retry_(util::makeRetryExponentialBackoff(retryDelay, RETRY_MAX_DELAY, strand_))
7881 , onConnect_(std::move(onConnect))
7982 , onDisconnect_(std::move(onDisconnect))
8083 , onLedgerClosed_(std::move(onLedgerClosed))
84+ , lastMessageTimeSecondsSinceEpoch_(PrometheusService::gaugeInt(
85+ " subscription_source_last_message_time" ,
86+ util::prometheus::Labels ({{" source" , fmt::format (" {}:{}" , ip, wsPort)}}),
87+ "Seconds since epoch of the last message received from rippled subscription streams"
88+ ))
8189{
8290 wsConnectionBuilder_.addHeader ({boost::beast::http::field::user_agent, " clio-client" })
8391 .addHeader ({" X-User" , " clio-client" })
84- .setConnectionTimeout (connectionTimeout );
92+ .setConnectionTimeout (wsTimeout_ );
8593}
8694
8795SubscriptionSource::~SubscriptionSource ()
@@ -167,21 +175,22 @@ SubscriptionSource::subscribe()
167175 }
168176
169177 wsConnection_ = std::move (connection).value ();
170- isConnected_ = true ;
171- onConnect_ ();
172- LOG (log_.info ()) << " Connected" ;
173178
174179 auto const & subscribeCommand = getSubscribeCommandJson ();
175- auto const writeErrorOpt = wsConnection_->write (subscribeCommand, yield);
180+ auto const writeErrorOpt = wsConnection_->write (subscribeCommand, yield, wsTimeout_ );
176181 if (writeErrorOpt) {
177182 handleError (writeErrorOpt.value (), yield);
178183 return ;
179184 }
180185
186+ isConnected_ = true ;
187+ LOG (log_.info ()) << " Connected" ;
188+ onConnect_ ();
189+
181190 retry_.reset ();
182191
183192 while (!stop_) {
184- auto const message = wsConnection_->read (yield);
193+ auto const message = wsConnection_->read (yield, wsTimeout_ );
185194 if (not message) {
186195 handleError (message.error (), yield);
187196 return ;
@@ -256,8 +265,6 @@ SubscriptionSource::handleMessage(std::string const& message)
256265 } else if (object.contains (JS (type)) && object.at (JS (type)) == JS_ManifestReceived) {
257266 LOG (log_.debug ()) << " Forwarding manifest: " << object;
258267 subscriptions_->forwardManifest (object);
259- } else {
260- LOG (log_.error ()) << " Unknown message: " << object;
261268 }
262269 }
263270 }
@@ -278,10 +285,10 @@ void
278285SubscriptionSource::handleError (util::requests::RequestError const & error, boost::asio::yield_context yield)
279286{
280287 isConnected_ = false ;
281- isForwarding_ = false ;
288+ bool const wasForwarding = isForwarding_. exchange ( false ) ;
282289 if (not stop_) {
283- onDisconnect_ ();
284290 LOG (log_.info ()) << " Disconnected" ;
291+ onDisconnect_ (wasForwarding);
285292 }
286293
287294 if (wsConnection_ != nullptr ) {
@@ -312,7 +319,11 @@ SubscriptionSource::logError(util::requests::RequestError const& error) const
312319void
313320SubscriptionSource::setLastMessageTime ()
314321{
315- lastMessageTime_.lock ().get () = std::chrono::steady_clock::now ();
322+ lastMessageTimeSecondsSinceEpoch_.get ().set (
323+ std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ()
324+ );
325+ auto lock = lastMessageTime_.lock ();
326+ lock.get () = std::chrono::steady_clock::now ();
316327}
317328
318329void
0 commit comments