22
33#include < chrono>
44#include < cstddef>
5+ #include < cstdlib>
56#include < memory>
67#include < mutex>
78#include < string>
@@ -144,11 +145,16 @@ RobotClient::~RobotClient() {
144145
145146void RobotClient::close () {
146147 should_refresh_.store (false );
148+ should_check_connection_ = false ;
147149
148150 if (refresh_thread_.joinable ()) {
149151 refresh_thread_.join ();
150152 }
151153
154+ if (check_connection_thread_.joinable ()) {
155+ check_connection_thread_.join ();
156+ }
157+
152158 stop_all ();
153159
154160 viam_channel_.close ();
@@ -231,6 +237,53 @@ void RobotClient::refresh_every() {
231237 }
232238};
233239
240+ void RobotClient::check_connection () {
241+ std::exception connection_error;
242+ bool connected (true );
243+ while (should_check_connection_) {
244+ for (int i = 0 ; i < 3 ; ++i) {
245+ try {
246+ std::this_thread::sleep_for (std::chrono::seconds{10 });
247+ impl::client_helper (impl_, &RobotService::Stub::ResourceNames).invoke ([](auto &) {
248+ return ;
249+ });
250+ connected = true ;
251+ break ;
252+ } catch (const std::exception& e) {
253+ connected = false ;
254+ connection_error = e;
255+ std::this_thread::sleep_for (std::chrono::milliseconds{100 });
256+ }
257+ }
258+ if (connected) {
259+ continue ;
260+ }
261+ const auto * uri = viam_channel_.uri_ ;
262+ VIAM_SDK_LOG (error)
263+ << " Lost connection to machine. Attempting to reconnect to every second" ;
264+ viam_channel_.close ();
265+
266+ for (int i = 0 ; i < 3 ; ++i) {
267+ try {
268+ auto channel = ViamChannel::dial (uri, {});
269+ auto impl =
270+ std::make_unique<RobotClient::impl>(RobotService::NewStub (channel.channel ()));
271+ impl_.reset ();
272+ impl_.swap (impl);
273+ refresh ();
274+ connected = true ;
275+ } catch (const std::exception& e) {
276+ viam_channel_.close ();
277+ std::this_thread::sleep_for (std::chrono::seconds{1 });
278+ }
279+ }
280+ if (!connected) {
281+ // NOLINTNEXTLINE
282+ exit (0 );
283+ }
284+ }
285+ }
286+
234287RobotClient::RobotClient (ViamChannel channel)
235288 : viam_channel_(std::move(channel)),
236289 impl_ (std::make_unique<impl>(RobotService::NewStub(viam_channel_.channel()))) {}
@@ -262,8 +315,8 @@ void RobotClient::log(const std::string& name,
262315 ClientContext ctx;
263316 const auto response = impl_->stub ->Log (ctx, req, &resp);
264317 if (is_error_response (response)) {
265- // Manually override to force this to get logged to console so we don't set off an infinite
266- // loop
318+ // Manually override to force this to get logged to console so we don't set off an
319+ // infinite loop
267320 VIAM_SDK_LOG (error) << boost::log::add_value (sdk::impl::attr_console_force_type{}, true )
268321 << " Error sending log message over grpc: " << response.error_message ()
269322 << response.error_details ();
@@ -279,6 +332,10 @@ std::shared_ptr<RobotClient> RobotClient::with_channel(ViamChannel channel,
279332 robot->refresh_thread_ = std::thread{&RobotClient::refresh_every, robot.get ()};
280333 }
281334
335+ robot->should_check_connection_ = true ;
336+
337+ robot->check_connection_thread_ = std::thread{&RobotClient::check_connection, robot.get ()};
338+
282339 robot->refresh ();
283340 return robot;
284341};
0 commit comments