Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit fe59d96

Browse files
authored
Migrate from 'grpc' crate to 'tonic'
## What is the goal of this PR? We migrated the code from using 'grpc' crate to 'tonic'. ## What are the changes implemented in this PR? Tonic is better-maintained and more active, so we should prefer it and use it across our Rust ecosystem.
2 parents 01e8251 + dcc4631 commit fe59d96

34 files changed

+981
-60529
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@
2222
.DS_Store
2323
.ijwb
2424
bazel-*
25+
target
26+
Cargo.lock
27+
Cargo.toml

BUILD

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,20 @@ load("@vaticle_bazel_distribution//crates:rules.bzl", "assemble_crate")
2626

2727
rust_library(
2828
name = "typedb_client",
29-
srcs = glob(["src/**/*.rs"], exclude = glob(["src/typedb_protocol/**/*.rs"])),
29+
srcs = glob(["src/**/*.rs"]),
3030
deps = [
31-
"//typedb_protocol",
31+
"@vaticle_typedb_protocol//grpc/rust:typedb_protocol",
3232

33+
"@vaticle_dependencies//library/crates:crossbeam",
3334
"@vaticle_dependencies//library/crates:futures",
34-
"@vaticle_dependencies//library/crates:grpc",
3535
"@vaticle_dependencies//library/crates:log",
36-
"@vaticle_dependencies//library/crates:protobuf",
36+
"@vaticle_dependencies//library/crates:prost",
37+
"@vaticle_dependencies//library/crates:tokio",
38+
"@vaticle_dependencies//library/crates:tonic",
3739
"@vaticle_dependencies//library/crates:uuid",
3840
],
3941
proc_macro_deps = [
40-
"@vaticle_dependencies//library/crates:derivative",
42+
"@vaticle_dependencies//library/crates:enum_dispatch",
4143
],
4244
tags = [
4345
"crate-name=typedb-client",
@@ -52,4 +54,12 @@ assemble_crate(
5254
homepage = "https://github.com/vaticle/typedb-client-rust",
5355
license = "apache",
5456
repository = "https://github.com/vaticle/typedb-client-rust",
55-
)
57+
)
58+
59+
# CI targets that are not declared in any BUILD file, but are called externally
60+
filegroup(
61+
name = "ci",
62+
data = [
63+
"@vaticle_dependencies//ide/rust:sync"
64+
],
65+
)

WORKSPACE

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_reg
3333
kotlin_repositories()
3434
kt_register_toolchains()
3535

36+
# TODO: enable this when we load @vaticle_typeql
37+
## Load //builder/antlr
38+
#load("@vaticle_dependencies//builder/antlr:deps.bzl", antlr_deps = "deps", "antlr_version")
39+
#antlr_deps()
40+
#
41+
#load("@rules_antlr//antlr:lang.bzl", "JAVA")
42+
#load("@rules_antlr//antlr:repositories.bzl", "rules_antlr_dependencies")
43+
#rules_antlr_dependencies(antlr_version, JAVA)
44+
45+
# Load //builder/grpc (required by @vaticle_typedb_protocol)
46+
load("@vaticle_dependencies//builder/grpc:deps.bzl", grpc_deps = "deps")
47+
grpc_deps()
48+
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl",
49+
com_github_grpc_grpc_deps = "grpc_deps")
50+
com_github_grpc_grpc_deps()
51+
3652
# Load //builder/rust
3753
load("@vaticle_dependencies//builder/rust:deps.bzl", rust_deps = "deps")
3854
rust_deps()
@@ -59,6 +75,13 @@ vaticle_dependencies_ci_pip()
5975
load("@vaticle_dependencies//distribution:deps.bzl", "vaticle_bazel_distribution")
6076
vaticle_bazel_distribution()
6177

78+
################################
79+
# Load @vaticle dependencies #
80+
################################
81+
82+
load("//dependencies/vaticle:repositories.bzl", "vaticle_typedb_protocol")
83+
vaticle_typedb_protocol()
84+
6285
############################
6386
# Load @maven dependencies #
6487
############################

dependencies/ide/sync.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (C) 2022 Vaticle
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU Affero General Public License as
7+
# published by the Free Software Foundation, either version 3 of the
8+
# License, or (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Affero General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Affero General Public License
16+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
#
18+
19+
bazel run @vaticle_dependencies//ide/rust:sync

dependencies/vaticle/repositories.bzl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,12 @@ def vaticle_dependencies():
2121
git_repository(
2222
name = "vaticle_dependencies",
2323
remote = "https://github.com/vaticle/dependencies",
24-
commit = "e3ba4970a3bb7db5e4725c0daa2a2a154ba9b3b8", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
24+
commit = "5be6d949ca1e04e4179ea6acb3432be713b9dfb8", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
25+
)
26+
27+
def vaticle_typedb_protocol():
28+
git_repository(
29+
name = "vaticle_typedb_protocol",
30+
remote = "https://github.com/vaticle/typedb-protocol",
31+
commit = "78e529dc5d40221aed5cc754906246b02f3635c2", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
2532
)

src/answer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub struct ConceptMap {
3030
}
3131

3232
impl ConceptMap {
33-
pub(crate) fn from_proto(proto: typedb_protocol::answer::ConceptMap) -> Result<Self> {
33+
pub(crate) fn from_proto(proto: typedb_protocol::ConceptMap) -> Result<Self> {
3434
let mut map = HashMap::with_capacity(proto.map.len());
3535
for (k, v) in proto.map {
3636
map.insert(k, Concept::from_proto(v)?);

src/common/error.rs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
* under the License.
2020
*/
2121

22-
use grpc::{Error as GrpcError, GrpcMessageError, GrpcStatus};
22+
// use grpc::{Error as GrpcError, GrpcMessageError, GrpcStatus};
2323
use std::error::Error as StdError;
2424
use std::fmt::{Debug, Display, Formatter};
25+
use tokio::sync::mpsc::error::SendError;
26+
use tonic::Status;
2527

2628
// TODO: try refactoring out the lifetime by storing String instead of &str
2729
struct MessageTemplate<'a> {
@@ -116,6 +118,7 @@ pub struct ClientMessages<'a> {
116118
pub cluster_replica_not_primary: Message<'a>,
117119
pub cluster_token_credential_invalid: Message<'a>,
118120
pub session_close_failed: Message<'a>,
121+
pub session_was_never_closed: Message<'a>,
119122
}
120123

121124
pub struct ConceptMessages<'a> {
@@ -137,10 +140,11 @@ impl Messages<'_> {
137140
unable_to_connect: Message::new(TEMPLATES.client, 5, "Unable to connect to TypeDB server."),
138141
db_does_not_exist: Message::new(TEMPLATES.client, 8, "The database '{}' does not exist."),
139142
missing_response_field: Message::new(TEMPLATES.client, 9, "Missing field in message received from server: '{}'."),
140-
unknown_request_id: Message::new(TEMPLATES.client, 10, "Received a response with unknown request id '{}':\n{}"),
143+
unknown_request_id: Message::new(TEMPLATES.client, 10, "Received a response with unknown request id '{}'"),
141144
cluster_replica_not_primary: Message::new(TEMPLATES.client, 13, "The replica is not the primary replica."),
142145
cluster_token_credential_invalid: Message::new(TEMPLATES.client, 16, "Invalid token credential."),
143-
session_close_failed: Message::new(TEMPLATES.client, 17, "Failed to close session. It may still be open on the server, or it may already have been closed previously.")
146+
session_close_failed: Message::new(TEMPLATES.client, 17, "Failed to close session. It may still be open on the server, or it may already have been closed previously."),
147+
session_was_never_closed: Message::new(TEMPLATES.client, 18, "A session went out of scope without being closed. Sessions should always be closed by awaiting Session::close."),
144148
},
145149
concept: ConceptMessages {
146150
invalid_concept_casting: Message::new(TEMPLATES.concept, 1, "Invalid concept conversion from '{}' to '{}'"),
@@ -153,14 +157,41 @@ pub const MESSAGES: Messages = Messages::new();
153157

154158
#[derive(Debug)]
155159
pub enum Error {
156-
GrpcError(String, GrpcError),
160+
// GrpcError(String, GrpcError),
157161
Other(String),
158162
}
159163

164+
impl Error {
165+
pub(crate) fn new(msg: String) -> Self {
166+
Error::Other(msg)
167+
}
168+
169+
// pub(crate) fn from_grpc(source: GrpcError) -> Self {
170+
// match source {
171+
// GrpcError::Http(_) => Error::GrpcError(String::from(MESSAGES.client.unable_to_connect), source),
172+
// GrpcError::GrpcMessage(ref err) => {
173+
// // TODO: this is awkward because we use gRPC errors to represent some user errors too
174+
// if Error::is_replica_not_primary(err) { Error::new(MESSAGES.client.cluster_replica_not_primary.format(vec![])) }
175+
// else if Error::is_token_credential_invalid(err) { Error::new(MESSAGES.client.cluster_token_credential_invalid.format(vec![])) }
176+
// else { Error::GrpcError(source.to_string().replacen("grpc message error: ", "", 1), source) }
177+
// },
178+
// _ => Error::GrpcError(source.to_string(), source)
179+
// }
180+
// }
181+
182+
// fn is_replica_not_primary(err: &GrpcMessageError) -> bool {
183+
// err.grpc_status == GrpcStatus::Internal as i32 && err.grpc_message.contains("[RPL01]")
184+
// }
185+
//
186+
// fn is_token_credential_invalid(err: &GrpcMessageError) -> bool {
187+
// err.grpc_status == GrpcStatus::Unauthenticated as i32 && err.grpc_message.contains("[CLS08]")
188+
// }
189+
}
190+
160191
impl Display for Error {
161192
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
162193
let message = match self {
163-
Error::GrpcError(msg, _) => msg,
194+
// Error::GrpcError(msg, _) => msg,
164195
Error::Other(msg) => msg
165196
};
166197
write!(f, "{}", message)
@@ -170,35 +201,26 @@ impl Display for Error {
170201
impl StdError for Error {
171202
fn source(&self) -> Option<&(dyn StdError + 'static)> {
172203
match self {
173-
Error::GrpcError(_, source) => Some(source),
204+
// Error::GrpcError(_, source) => Some(source),
174205
Error::Other(_) => None
175206
}
176207
}
177208
}
178209

179-
impl Error {
180-
pub(crate) fn new(msg: String) -> Self {
181-
Error::Other(msg)
182-
}
183-
184-
pub(crate) fn from_grpc(source: GrpcError) -> Self {
185-
match source {
186-
GrpcError::Http(_) => Error::GrpcError(String::from(MESSAGES.client.unable_to_connect), source),
187-
GrpcError::GrpcMessage(ref err) => {
188-
// TODO: this is awkward because we use gRPC errors to represent some user errors too
189-
if Error::is_replica_not_primary(err) { Error::new(MESSAGES.client.cluster_replica_not_primary.format(vec![])) }
190-
else if Error::is_token_credential_invalid(err) { Error::new(MESSAGES.client.cluster_token_credential_invalid.format(vec![])) }
191-
else { Error::GrpcError(source.to_string().replacen("grpc message error: ", "", 1), source) }
192-
},
193-
_ => Error::GrpcError(source.to_string(), source)
194-
}
210+
impl From<Status> for Error {
211+
fn from(status: Status) -> Self {
212+
Error::Other(status.to_string())
195213
}
214+
}
196215

197-
fn is_replica_not_primary(err: &GrpcMessageError) -> bool {
198-
err.grpc_status == GrpcStatus::Internal as i32 && err.grpc_message.contains("[RPL01]")
216+
impl From<futures::channel::mpsc::SendError> for Error {
217+
fn from(err: futures::channel::mpsc::SendError) -> Self {
218+
Error::Other(err.to_string())
199219
}
220+
}
200221

201-
fn is_token_credential_invalid(err: &GrpcMessageError) -> bool {
202-
err.grpc_status == GrpcStatus::Unauthenticated as i32 && err.grpc_message.contains("[CLS08]")
222+
impl<T> From<tokio::sync::mpsc::error::SendError<T>> for Error {
223+
fn from(err: tokio::sync::mpsc::error::SendError<T>) -> Self {
224+
Error::Other(err.to_string())
203225
}
204226
}

0 commit comments

Comments
 (0)