-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of MessageReceiver and MessagePipe. #2
Conversation
FWIW, the |
6c46e0b
to
28a0806
Compare
Maybe we should use prost instead of |
We use gRPC and protobufs at work with Rust as the server and it works really well for us. This is (roughly) our setup:
The build script for compiling the language bindings is a bit non-trivial because we have many proto files and also import the well-known types (which are also vendored in the Language bindings build script// vendor/proto/build.rs
use std::{
error::Error,
ffi::OsStr,
path::{Path, PathBuf},
};
use walkdir::WalkDir;
fn main() -> Result<(), Box<dyn Error>> {
let crate_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let project_root = crate_dir.parent().unwrap().parent().unwrap();
let with_grpc = std::env::var("CARGO_FEATURE_GRPC_SERVICES").is_ok();
compile_all_protobufs(&project_root, with_grpc)?;
Ok(())
}
fn compile_all_protobufs(
project_root: &Path,
with_grpc: bool,
) -> Result<(), Box<dyn Error>> {
let proto_files = find_proto_files(project_root, &["project_1", "project_2"])?;
for file in &proto_files {
println!("cargo:rerun-if-changed={}", file.display());
}
let format = rustfmt_is_available();
if !format {
println!("cargo:warning=The generated bindings won't be formatted because rustfmt isn't installed.");
}
tonic_build::configure()
.build_client(with_grpc)
.build_server(with_grpc)
.format(format)
.compile(&proto_files, &[project_root.to_path_buf()])?;
Ok(())
}
fn rustfmt_is_available() -> bool {
use std::process::{Command, Stdio};
let status = Command::new("rustfmt")
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status();
match status {
Ok(s) => s.success(),
Err(_) => false,
}
}
fn find_proto_files(
project_root: &Path,
folders: &[&str],
) -> Result<Vec<PathBuf>, Box<dyn Error>> {
let mut paths = Vec::new();
for folder in folders {
let entries = WalkDir::new(project_root.join(folder))
.contents_first(true)
.into_iter()
.filter_entry(|e| {
e.path().extension() == Some(OsStr::new("proto"))
});
for entry in entries {
paths.push(entry?.into_path());
}
}
Ok(paths)
} From there, you can use Importing generated code// vendor/src/lib.rs
//! Rust bindings to the various [Protocol Buffer][pb] messages used at company.
//!
//! [pb]: https://developers.google.com/protocol-buffers
pub mod project_1 {
/// Automatically generated messages used by foo.
///
/// See `project_1/foo/bar.proto` for more.
pub mod bar {
include!(concat!(
env!("OUT_DIR"),
"/",
"company.project_1.foo.bar.rs"
));
}
}
/// Protocol Buffers used by project 2.
pub mod project_2 {
pub mod foo{
include!(concat!(
env!("OUT_DIR"),
"/",
"company.project_2.foo.rs"
));
}
pub mod server {
include!(concat!(env!("OUT_DIR"), "/", "company.project_2.server.rs"));
}
pub mod bar {
include!(concat!(env!("OUT_DIR"), "/", "company.project_2.bar.rs"));
}
} We also have a
Git submodules work really well for keeping things in sync with a 3rd party project. If upstream has new changes, you just need to run
It seems pretty straightforward. Each The GPL is a bit too restrictive for my liking, but considering we directly import/copy their files we have no choice but to make this project GPLv3 as well. I had to do the same with |
I looked both up on crates.io before I started this, |
That sounds right for a larger project, but for just those four Proto files I would just have them in this repository, I think.
Looks mostly as what I'm doing. I don't think we can use tonic, however, because Signal doesn't seem to use gRPC.
I'd think I wouldn't have that issue with
That's mostly how we structure this project too.
I'm hesitant to pulling in the whole
I have no issues with GPLv3 myself, and I figured the repo should be GPLv3 anyhow, because -protocol is already GPLv3 and we're looking at a ton of GPLv3 code to port from the Java and C versions. Either way, I was wondering whether we had to make an additional effort to acknowledge that we directly compile upstream code, I'm not sure what the GPL says about that. I seem to recall there was something to it. It probably doesn't matter for now. Let's first get something to work; we're in the green either way. |
So, they're in OUT_DIR now, and If everyone agrees to stay on |
fc7c3aa
to
4436476
Compare
Good news, I'm at the point where |
(merged the protobuf stuff already) |
Halfy verified working with Whisperfish.
de2dfd1
to
0a28420
Compare
In its current state, the messages get acknowledged as soon as they come over the socket. This mirrors the Java implementation, but I dislike this approach. I would like the application to tell when the message is actually stored. This also means I just lost a few months of messages 😭 |
75491b5
to
2658326
Compare
We even have a single unit test now! :'-) |
ServiceCipher will be in a next branch. Gonna get this in master now. |
Signal protobuf compilation
These files should be kept in sync with the
protobuf
directory oflibsignal-service-java
.It would be cleaner to yield the compiled files OUT_DIR, but that gets ugly very fast because of rust-lang/rust#48250.
protoc
, or do we yield the choice to the dependee?Since we adopted
prost
, we're bound toprotoc
..proto
files in this repo, LICENSE-wise?We don't think there's anything to do, beyond licensing this crate under GPLv3.
This part is merged.
MessageReceiver
MessagePipe
ServiceCipher
(possibly in a next branch, not sure yet)
Misc