Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/viam/examples/modules/complex/proto/buf.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 546238c53f7340c6a2a6099fb863bc1b
digest: shake256:8d75c12f391e392b24c076d05117b47aeddb090add99c70247a8f4389b906a65f61a933c68e54ed8b73a050b967b6b712ba194348b67c3ab3ee26cc2cb25852c
commit: 751cbe31638d43a9bfb6162cd2352e67
digest: shake256:87f55470d9d124e2d1dedfe0231221f4ed7efbc55bc5268917c678e2d9b9c41573a7f9a557f6d8539044524d9fc5ca8fbb7db05eb81379d168285d76b57eb8a4
2 changes: 1 addition & 1 deletion src/viam/sdk/robot/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ std::shared_ptr<RobotClient> RobotClient::with_channel(std::shared_ptr<ViamChann
std::shared_ptr<RobotClient> RobotClient::at_address(const std::string& address,
const Options& options) {
const char* uri = address.c_str();
auto channel = ViamChannel::dial(uri, options.dial_options());
auto channel = ViamChannel::dial_initial(uri, options.dial_options());
std::shared_ptr<RobotClient> robot = RobotClient::with_channel(channel, options);
robot->should_close_channel_ = true;

Expand Down
67 changes: 62 additions & 5 deletions src/viam/sdk/rpc/dial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <istream>
#include <string>

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

DialOptions::DialOptions() = default;

void DialOptions::set_credentials(boost::optional<Credentials> creds) {
DialOptions& DialOptions::set_credentials(boost::optional<Credentials> creds) {
credentials_ = std::move(creds);

return *this;
}

void DialOptions::set_entity(boost::optional<std::string> entity) {
DialOptions& DialOptions::set_entity(boost::optional<std::string> entity) {
auth_entity_ = std::move(entity);

return *this;
}

DialOptions& DialOptions::set_initial_connection_attempts(int attempts) {
initial_connection_attempts_ = attempts;

return *this;
}

void DialOptions::set_timeout(std::chrono::duration<float> timeout) {
timeout_ = std::move(timeout);
DialOptions& DialOptions::set_timeout(std::chrono::duration<float> timeout) {
timeout_ = timeout;

return *this;
}

DialOptions& DialOptions::set_initial_connection_attempt_timeout(
std::chrono::duration<float> timeout) {
initial_connection_attempt_timeout_ = timeout;

return *this;
}

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

int DialOptions::initial_connection_attempts() const {
return initial_connection_attempts_;
}

const std::chrono::duration<float>& DialOptions::timeout() const {
return timeout_;
}

void DialOptions::set_allow_insecure_downgrade(bool allow) {
std::chrono::duration<float> DialOptions::initial_connection_attempt_timeout() const {
return initial_connection_attempt_timeout_;
}

DialOptions& DialOptions::set_allow_insecure_downgrade(bool allow) {
allow_insecure_downgrade_ = allow;

return *this;
}

bool DialOptions::allows_insecure_downgrade() const {
return allow_insecure_downgrade_;
}

std::shared_ptr<ViamChannel> ViamChannel::dial_initial(
const char* uri, const boost::optional<DialOptions>& options) {
DialOptions opts = options.get_value_or(DialOptions());
auto timeout = opts.timeout();
auto attempts_remaining = opts.initial_connection_attempts();
if (attempts_remaining == 0) {
attempts_remaining = -1;
}
opts.set_timeout(opts.initial_connection_attempt_timeout());

while (attempts_remaining != 0) {
try {
auto connection = dial(uri, opts);
opts.set_timeout(timeout);
return connection;
} catch (const std::exception& e) {
attempts_remaining -= 1;
if (attempts_remaining == 0) {
throw e;
}
}
}
// the while loop will run until we either return or throw an error, so we can never reach this
// point
BOOST_UNREACHABLE_RETURN(nullptr)
}

std::shared_ptr<ViamChannel> ViamChannel::dial(const char* uri,
const boost::optional<DialOptions>& options) {
void* ptr = init_rust_runtime();
Expand Down
37 changes: 33 additions & 4 deletions src/viam/sdk/rpc/dial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,26 @@ class ViamChannel {
public:
void close();
ViamChannel(std::shared_ptr<GrpcChannel> channel, const char* path, void* runtime);

/// @brief Connects to a robot at the given URI address, using the provided dial options (or
/// default options is none are provided). Ignores initial connection options specifying
/// how many times to attempt to connect and with what timeout.
/// In general, use of this method is discouraged. `RobotClient::at_address(...)` is the
/// preferred method to connect to a robot, and creates the channel itself.
/// @throws Exception if it is unable to establish a connection to the provided URI
static std::shared_ptr<ViamChannel> dial(const char* uri,
const boost::optional<DialOptions>& options);

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

const std::shared_ptr<GrpcChannel>& channel() const;

private:
Expand Down Expand Up @@ -49,11 +66,15 @@ class DialOptions {
const boost::optional<std::string>& entity() const;
bool allows_insecure_downgrade() const;
const std::chrono::duration<float>& timeout() const;
int initial_connection_attempts() const;
std::chrono::duration<float> initial_connection_attempt_timeout() const;

void set_entity(boost::optional<std::string> entity);
void set_credentials(boost::optional<Credentials> creds);
void set_allow_insecure_downgrade(bool allow);
void set_timeout(std::chrono::duration<float> timeout);
DialOptions& set_entity(boost::optional<std::string> entity);
DialOptions& set_credentials(boost::optional<Credentials> creds);
DialOptions& set_allow_insecure_downgrade(bool allow);
DialOptions& set_timeout(std::chrono::duration<float> timeout);
DialOptions& set_initial_connection_attempts(int attempts);
DialOptions& set_initial_connection_attempt_timeout(std::chrono::duration<float> timeout);

private:
// TODO (RSDK-917): We currently don't provide a flag for disabling webRTC, instead relying on a
Expand All @@ -72,6 +93,14 @@ class DialOptions {
/// @brief Duration before the dial connection times out
/// Set to 20sec to match _defaultOfferDeadline in goutils/rpc/wrtc_call_queue.go
std::chrono::duration<float> timeout_{20};

/// @brief Number of attempts to make when initially connecting to a robot
/// If set to 0 or a negative integer, will attempt to reconnect forever.
int initial_connection_attempts_ = 3;

/// @brief Timeout of connection attempts when initially dialing a robot
/// Defaults to 20sec to match the default timeout duration
std::chrono::duration<float> initial_connection_attempt_timeout_{20};
};

class Options {
Expand Down