Skip to content

Commit 3d58df1

Browse files
authored
RSDK-6158 - initial connection options (#376)
1 parent 5935eb3 commit 3d58df1

File tree

4 files changed

+98
-12
lines changed

4 files changed

+98
-12
lines changed

src/viam/examples/modules/complex/proto/buf.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ deps:
44
- remote: buf.build
55
owner: googleapis
66
repository: googleapis
7-
commit: 546238c53f7340c6a2a6099fb863bc1b
8-
digest: shake256:8d75c12f391e392b24c076d05117b47aeddb090add99c70247a8f4389b906a65f61a933c68e54ed8b73a050b967b6b712ba194348b67c3ab3ee26cc2cb25852c
7+
commit: 751cbe31638d43a9bfb6162cd2352e67
8+
digest: shake256:87f55470d9d124e2d1dedfe0231221f4ed7efbc55bc5268917c678e2d9b9c41573a7f9a557f6d8539044524d9fc5ca8fbb7db05eb81379d168285d76b57eb8a4

src/viam/sdk/robot/client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ std::shared_ptr<RobotClient> RobotClient::with_channel(std::shared_ptr<ViamChann
256256
std::shared_ptr<RobotClient> RobotClient::at_address(const std::string& address,
257257
const Options& options) {
258258
const char* uri = address.c_str();
259-
auto channel = ViamChannel::dial(uri, options.dial_options());
259+
auto channel = ViamChannel::dial_initial(uri, options.dial_options());
260260
std::shared_ptr<RobotClient> robot = RobotClient::with_channel(channel, options);
261261
robot->should_close_channel_ = true;
262262

src/viam/sdk/rpc/dial.cpp

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <istream>
44
#include <string>
55

6+
#include <boost/config.hpp>
67
#include <boost/none.hpp>
78
#include <boost/optional.hpp>
89
#include <grpcpp/channel.h>
@@ -52,16 +53,35 @@ ViamChannel::ViamChannel(std::shared_ptr<grpc::Channel> channel, const char* pat
5253

5354
DialOptions::DialOptions() = default;
5455

55-
void DialOptions::set_credentials(boost::optional<Credentials> creds) {
56+
DialOptions& DialOptions::set_credentials(boost::optional<Credentials> creds) {
5657
credentials_ = std::move(creds);
58+
59+
return *this;
5760
}
5861

59-
void DialOptions::set_entity(boost::optional<std::string> entity) {
62+
DialOptions& DialOptions::set_entity(boost::optional<std::string> entity) {
6063
auth_entity_ = std::move(entity);
64+
65+
return *this;
66+
}
67+
68+
DialOptions& DialOptions::set_initial_connection_attempts(int attempts) {
69+
initial_connection_attempts_ = attempts;
70+
71+
return *this;
6172
}
6273

63-
void DialOptions::set_timeout(std::chrono::duration<float> timeout) {
64-
timeout_ = std::move(timeout);
74+
DialOptions& DialOptions::set_timeout(std::chrono::duration<float> timeout) {
75+
timeout_ = timeout;
76+
77+
return *this;
78+
}
79+
80+
DialOptions& DialOptions::set_initial_connection_attempt_timeout(
81+
std::chrono::duration<float> timeout) {
82+
initial_connection_attempt_timeout_ = timeout;
83+
84+
return *this;
6585
}
6686

6787
const boost::optional<std::string>& DialOptions::entity() const {
@@ -72,18 +92,55 @@ const boost::optional<Credentials>& DialOptions::credentials() const {
7292
return credentials_;
7393
}
7494

95+
int DialOptions::initial_connection_attempts() const {
96+
return initial_connection_attempts_;
97+
}
98+
7599
const std::chrono::duration<float>& DialOptions::timeout() const {
76100
return timeout_;
77101
}
78102

79-
void DialOptions::set_allow_insecure_downgrade(bool allow) {
103+
std::chrono::duration<float> DialOptions::initial_connection_attempt_timeout() const {
104+
return initial_connection_attempt_timeout_;
105+
}
106+
107+
DialOptions& DialOptions::set_allow_insecure_downgrade(bool allow) {
80108
allow_insecure_downgrade_ = allow;
109+
110+
return *this;
81111
}
82112

83113
bool DialOptions::allows_insecure_downgrade() const {
84114
return allow_insecure_downgrade_;
85115
}
86116

117+
std::shared_ptr<ViamChannel> ViamChannel::dial_initial(
118+
const char* uri, const boost::optional<DialOptions>& options) {
119+
DialOptions opts = options.get_value_or(DialOptions());
120+
auto timeout = opts.timeout();
121+
auto attempts_remaining = opts.initial_connection_attempts();
122+
if (attempts_remaining == 0) {
123+
attempts_remaining = -1;
124+
}
125+
opts.set_timeout(opts.initial_connection_attempt_timeout());
126+
127+
while (attempts_remaining != 0) {
128+
try {
129+
auto connection = dial(uri, opts);
130+
opts.set_timeout(timeout);
131+
return connection;
132+
} catch (const std::exception& e) {
133+
attempts_remaining -= 1;
134+
if (attempts_remaining == 0) {
135+
throw e;
136+
}
137+
}
138+
}
139+
// the while loop will run until we either return or throw an error, so we can never reach this
140+
// point
141+
BOOST_UNREACHABLE_RETURN(nullptr)
142+
}
143+
87144
std::shared_ptr<ViamChannel> ViamChannel::dial(const char* uri,
88145
const boost::optional<DialOptions>& options) {
89146
void* ptr = init_rust_runtime();

src/viam/sdk/rpc/dial.hpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,26 @@ class ViamChannel {
1616
public:
1717
void close();
1818
ViamChannel(std::shared_ptr<GrpcChannel> channel, const char* path, void* runtime);
19+
20+
/// @brief Connects to a robot at the given URI address, using the provided dial options (or
21+
/// default options is none are provided). Ignores initial connection options specifying
22+
/// how many times to attempt to connect and with what timeout.
23+
/// In general, use of this method is discouraged. `RobotClient::at_address(...)` is the
24+
/// preferred method to connect to a robot, and creates the channel itself.
25+
/// @throws Exception if it is unable to establish a connection to the provided URI
1926
static std::shared_ptr<ViamChannel> dial(const char* uri,
2027
const boost::optional<DialOptions>& options);
2128

29+
// @brief Dials to a robot at the given URI address, using the provided dial options (or default
30+
// options is none are provided). Additionally specifies that this dial is an initial connection
31+
// attempt and so uses the initial connection options.
32+
/// In general, use of this method is discouraged. `RobotClient::at_address(...)` is the
33+
/// preferred method to connect to a robot, and creates the channel itself.
34+
/// @throws Exception if it is unable to establish a connection to the provided URI within
35+
/// the given number of initial connection attempts
36+
static std::shared_ptr<ViamChannel> dial_initial(const char* uri,
37+
const boost::optional<DialOptions>& options);
38+
2239
const std::shared_ptr<GrpcChannel>& channel() const;
2340

2441
private:
@@ -49,11 +66,15 @@ class DialOptions {
4966
const boost::optional<std::string>& entity() const;
5067
bool allows_insecure_downgrade() const;
5168
const std::chrono::duration<float>& timeout() const;
69+
int initial_connection_attempts() const;
70+
std::chrono::duration<float> initial_connection_attempt_timeout() const;
5271

53-
void set_entity(boost::optional<std::string> entity);
54-
void set_credentials(boost::optional<Credentials> creds);
55-
void set_allow_insecure_downgrade(bool allow);
56-
void set_timeout(std::chrono::duration<float> timeout);
72+
DialOptions& set_entity(boost::optional<std::string> entity);
73+
DialOptions& set_credentials(boost::optional<Credentials> creds);
74+
DialOptions& set_allow_insecure_downgrade(bool allow);
75+
DialOptions& set_timeout(std::chrono::duration<float> timeout);
76+
DialOptions& set_initial_connection_attempts(int attempts);
77+
DialOptions& set_initial_connection_attempt_timeout(std::chrono::duration<float> timeout);
5778

5879
private:
5980
// TODO (RSDK-917): We currently don't provide a flag for disabling webRTC, instead relying on a
@@ -72,6 +93,14 @@ class DialOptions {
7293
/// @brief Duration before the dial connection times out
7394
/// Set to 20sec to match _defaultOfferDeadline in goutils/rpc/wrtc_call_queue.go
7495
std::chrono::duration<float> timeout_{20};
96+
97+
/// @brief Number of attempts to make when initially connecting to a robot
98+
/// If set to 0 or a negative integer, will attempt to reconnect forever.
99+
int initial_connection_attempts_ = 3;
100+
101+
/// @brief Timeout of connection attempts when initially dialing a robot
102+
/// Defaults to 20sec to match the default timeout duration
103+
std::chrono::duration<float> initial_connection_attempt_timeout_{20};
75104
};
76105

77106
class Options {

0 commit comments

Comments
 (0)