Skip to content

Commit ebbb58e

Browse files
authored
Merge pull request #172 from jsturtevant/windows3
Windows Support for Sync implementation
2 parents 78de1c5 + 4975099 commit ebbb58e

28 files changed

+1069
-298
lines changed

.github/workflows/bvt.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
runs-on: ${{ matrix.os }}
77
strategy:
88
matrix:
9-
os: [ubuntu-latest, macos-latest]
9+
os: [ubuntu-latest, macos-latest, windows-latest]
1010
steps:
1111
- name: Checkout
1212
uses: actions/checkout@v3
@@ -22,7 +22,7 @@ jobs:
2222
runs-on: ${{ matrix.os }}
2323
strategy:
2424
matrix:
25-
os: [ubuntu-latest, macos-latest]
25+
os: [ubuntu-latest, macos-latest, windows-latest]
2626
steps:
2727
- name: Checkout
2828
uses: actions/checkout@v3

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,22 @@ nix = "0.23.0"
1717
log = "0.4"
1818
byteorder = "1.3.2"
1919
thiserror = "1.0"
20-
2120
async-trait = { version = "0.1.31", optional = true }
2221
tokio = { version = "1", features = ["rt", "sync", "io-util", "macros", "time"], optional = true }
2322
futures = { version = "0.3", optional = true }
2423

24+
[target.'cfg(windows)'.dependencies]
25+
windows-sys = {version = "0.45", features = [ "Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Pipes", "Win32_Security", "Win32_System_Threading"]}
26+
2527
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
2628
tokio-vsock = { version = "0.3.1", optional = true }
2729

2830
[build-dependencies]
2931
protobuf-codegen = "3.1.0"
3032

33+
[dev-dependencies]
34+
assert_cmd = "2.0.7"
35+
3136
[features]
3237
default = ["sync"]
3338
async = ["async-trait", "tokio", "futures", "tokio-vsock"]

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ build: debug
2323

2424
.PHONY: test
2525
test:
26+
ifeq ($OS,Windows_NT)
27+
# async isn't enabled for windows, don't test that feature
28+
cargo test --verbose
29+
else
2630
cargo test --all-features --verbose
27-
31+
endif
32+
2833
.PHONY: check
2934
check:
3035
cargo fmt --all -- --check

example/async-client.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55

66
mod protocols;
77
mod utils;
8-
8+
#[cfg(unix)]
99
use protocols::r#async::{agent, agent_ttrpc, health, health_ttrpc};
1010
use ttrpc::context::{self, Context};
11+
#[cfg(unix)]
1112
use ttrpc::r#async::Client;
1213

14+
#[cfg(windows)]
15+
fn main() {
16+
println!("This example only works on Unix-like OSes");
17+
}
18+
19+
#[cfg(unix)]
1320
#[tokio::main(flavor = "current_thread")]
1421
async fn main() {
1522
let c = Client::connect(utils::SOCK_ADDR).unwrap();

example/async-server.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,22 @@ use std::sync::Arc;
1313

1414
use log::LevelFilter;
1515

16+
#[cfg(unix)]
1617
use protocols::r#async::{agent, agent_ttrpc, health, health_ttrpc, types};
18+
#[cfg(unix)]
1719
use ttrpc::asynchronous::Server;
1820
use ttrpc::error::{Error, Result};
1921
use ttrpc::proto::{Code, Status};
2022

23+
#[cfg(unix)]
2124
use async_trait::async_trait;
25+
#[cfg(unix)]
2226
use tokio::signal::unix::{signal, SignalKind};
2327
use tokio::time::sleep;
2428

2529
struct HealthService;
2630

31+
#[cfg(unix)]
2732
#[async_trait]
2833
impl health_ttrpc::Health for HealthService {
2934
async fn check(
@@ -58,7 +63,7 @@ impl health_ttrpc::Health for HealthService {
5863
}
5964

6065
struct AgentService;
61-
66+
#[cfg(unix)]
6267
#[async_trait]
6368
impl agent_ttrpc::AgentService for AgentService {
6469
async fn list_interfaces(
@@ -82,6 +87,12 @@ impl agent_ttrpc::AgentService for AgentService {
8287
}
8388
}
8489

90+
#[cfg(windows)]
91+
fn main() {
92+
println!("This example only works on Unix-like OSes");
93+
}
94+
95+
#[cfg(unix)]
8596
#[tokio::main(flavor = "current_thread")]
8697
async fn main() {
8798
simple_logging::log_to_stderr(LevelFilter::Trace);

example/async-stream-client.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55

66
mod protocols;
77
mod utils;
8-
8+
#[cfg(unix)]
99
use protocols::r#async::{empty, streaming, streaming_ttrpc};
1010
use ttrpc::context::{self, Context};
11+
#[cfg(unix)]
1112
use ttrpc::r#async::Client;
1213

14+
#[cfg(windows)]
15+
fn main() {
16+
println!("This example only works on Unix-like OSes");
17+
}
18+
19+
#[cfg(unix)]
1320
#[tokio::main(flavor = "current_thread")]
1421
async fn main() {
1522
simple_logging::log_to_stderr(log::LevelFilter::Info);
@@ -48,6 +55,7 @@ fn default_ctx() -> Context {
4855
ctx
4956
}
5057

58+
#[cfg(unix)]
5159
async fn echo_request(cli: streaming_ttrpc::StreamingClient) {
5260
let echo1 = streaming::EchoPayload {
5361
seq: 1,
@@ -59,6 +67,7 @@ async fn echo_request(cli: streaming_ttrpc::StreamingClient) {
5967
assert_eq!(resp.seq, echo1.seq + 1);
6068
}
6169

70+
#[cfg(unix)]
6271
async fn echo_stream(cli: streaming_ttrpc::StreamingClient) {
6372
let mut stream = cli.echo_stream(default_ctx()).await.unwrap();
6473

@@ -81,6 +90,7 @@ async fn echo_stream(cli: streaming_ttrpc::StreamingClient) {
8190
assert!(matches!(ret, Err(ttrpc::Error::Eof)));
8291
}
8392

93+
#[cfg(unix)]
8494
async fn sum_stream(cli: streaming_ttrpc::StreamingClient) {
8595
let mut stream = cli.sum_stream(default_ctx()).await.unwrap();
8696

@@ -108,6 +118,7 @@ async fn sum_stream(cli: streaming_ttrpc::StreamingClient) {
108118
assert_eq!(ssum.num, sum.num);
109119
}
110120

121+
#[cfg(unix)]
111122
async fn divide_stream(cli: streaming_ttrpc::StreamingClient) {
112123
let expected = streaming::Sum {
113124
sum: 392,
@@ -127,6 +138,7 @@ async fn divide_stream(cli: streaming_ttrpc::StreamingClient) {
127138
assert_eq!(actual.num, expected.num);
128139
}
129140

141+
#[cfg(unix)]
130142
async fn echo_null(cli: streaming_ttrpc::StreamingClient) {
131143
let mut stream = cli.echo_null(default_ctx()).await.unwrap();
132144

@@ -142,6 +154,7 @@ async fn echo_null(cli: streaming_ttrpc::StreamingClient) {
142154
assert_eq!(res, empty::Empty::new());
143155
}
144156

157+
#[cfg(unix)]
145158
async fn echo_null_stream(cli: streaming_ttrpc::StreamingClient) {
146159
let stream = cli.echo_null_stream(default_ctx()).await.unwrap();
147160

example/async-stream-server.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,20 @@ use std::sync::Arc;
1010

1111
use log::{info, LevelFilter};
1212

13+
#[cfg(unix)]
1314
use protocols::r#async::{empty, streaming, streaming_ttrpc};
15+
#[cfg(unix)]
1416
use ttrpc::asynchronous::Server;
1517

18+
#[cfg(unix)]
1619
use async_trait::async_trait;
20+
#[cfg(unix)]
1721
use tokio::signal::unix::{signal, SignalKind};
1822
use tokio::time::sleep;
1923

2024
struct StreamingService;
2125

26+
#[cfg(unix)]
2227
#[async_trait]
2328
impl streaming_ttrpc::Streaming for StreamingService {
2429
async fn echo(
@@ -131,6 +136,12 @@ impl streaming_ttrpc::Streaming for StreamingService {
131136
}
132137
}
133138

139+
#[cfg(windows)]
140+
fn main() {
141+
println!("This example only works on Unix-like OSes");
142+
}
143+
144+
#[cfg(unix)]
134145
#[tokio::main(flavor = "current_thread")]
135146
async fn main() {
136147
simple_logging::log_to_stderr(LevelFilter::Info);

example/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn main() {
4545
async_all: true,
4646
..Default::default()
4747
})
48-
.rust_protobuf_customize(protobuf_customized.clone())
48+
.rust_protobuf_customize(protobuf_customized)
4949
.run()
5050
.expect("Gen async code failed.");
5151

@@ -75,7 +75,7 @@ fn replace_text_in_file(file_name: &str, from: &str, to: &str) -> Result<(), std
7575

7676
let new_contents = contents.replace(from, to);
7777

78-
let mut dst = File::create(&file_name)?;
78+
let mut dst = File::create(file_name)?;
7979
dst.write(new_contents.as_bytes())?;
8080

8181
Ok(())

example/client.rs

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
mod protocols;
1616
mod utils;
1717

18+
use log::LevelFilter;
1819
use protocols::sync::{agent, agent_ttrpc, health, health_ttrpc};
1920
use std::thread;
2021
use ttrpc::context::{self, Context};
22+
use ttrpc::error::Error;
23+
use ttrpc::proto::Code;
2124
use ttrpc::Client;
2225

2326
fn main() {
27+
simple_logging::log_to_stderr(LevelFilter::Trace);
28+
2429
let c = Client::connect(utils::SOCK_ADDR).unwrap();
2530
let hc = health_ttrpc::HealthClient::new(c.clone());
2631
let ac = agent_ttrpc::AgentServiceClient::new(c);
@@ -33,69 +38,97 @@ fn main() {
3338
let t = thread::spawn(move || {
3439
let req = health::CheckRequest::new();
3540
println!(
36-
"OS Thread {:?} - {} started: {:?}",
41+
"OS Thread {:?} - health.check() started: {:?}",
3742
std::thread::current().id(),
38-
"health.check()",
3943
now.elapsed(),
4044
);
45+
46+
let rsp = thc.check(default_ctx(), &req);
47+
match rsp.as_ref() {
48+
Err(Error::RpcStatus(s)) => {
49+
assert_eq!(Code::NOT_FOUND, s.code());
50+
assert_eq!("Just for fun".to_string(), s.message())
51+
}
52+
Err(e) => {
53+
panic!("not expecting an error from the example server: {:?}", e)
54+
}
55+
Ok(x) => {
56+
panic!("not expecting a OK response from the example server: {:?}", x)
57+
}
58+
}
4159
println!(
42-
"OS Thread {:?} - {} -> {:?} ended: {:?}",
60+
"OS Thread {:?} - health.check() -> {:?} ended: {:?}",
4361
std::thread::current().id(),
44-
"health.check()",
45-
thc.check(default_ctx(), &req),
62+
rsp,
4663
now.elapsed(),
4764
);
4865
});
4966

5067
let t2 = thread::spawn(move || {
5168
println!(
52-
"OS Thread {:?} - {} started: {:?}",
69+
"OS Thread {:?} - agent.list_interfaces() started: {:?}",
5370
std::thread::current().id(),
54-
"agent.list_interfaces()",
5571
now.elapsed(),
5672
);
5773

5874
let show = match tac.list_interfaces(default_ctx(), &agent::ListInterfacesRequest::new()) {
59-
Err(e) => format!("{:?}", e),
60-
Ok(s) => format!("{:?}", s),
75+
Err(e) => {
76+
panic!("not expecting an error from the example server: {:?}", e)
77+
}
78+
Ok(s) => {
79+
assert_eq!("first".to_string(), s.Interfaces[0].name);
80+
assert_eq!("second".to_string(), s.Interfaces[1].name);
81+
format!("{s:?}")
82+
}
6183
};
6284

6385
println!(
64-
"OS Thread {:?} - {} -> {} ended: {:?}",
86+
"OS Thread {:?} - agent.list_interfaces() -> {} ended: {:?}",
6587
std::thread::current().id(),
66-
"agent.list_interfaces()",
6788
show,
6889
now.elapsed(),
6990
);
7091
});
7192

7293
println!(
73-
"Main OS Thread - {} started: {:?}",
74-
"agent.online_cpu_mem()",
94+
"Main OS Thread - agent.online_cpu_mem() started: {:?}",
7595
now.elapsed()
7696
);
7797
let show = match ac.online_cpu_mem(default_ctx(), &agent::OnlineCPUMemRequest::new()) {
78-
Err(e) => format!("{:?}", e),
79-
Ok(s) => format!("{:?}", s),
98+
Err(Error::RpcStatus(s)) => {
99+
assert_eq!(Code::NOT_FOUND, s.code());
100+
assert_eq!(
101+
"/grpc.AgentService/OnlineCPUMem is not supported".to_string(),
102+
s.message()
103+
);
104+
format!("{s:?}")
105+
}
106+
Err(e) => {
107+
panic!("not expecting an error from the example server: {:?}", e)
108+
}
109+
Ok(s) => {
110+
panic!("not expecting a OK response from the example server: {:?}", s)
111+
}
80112
};
81113
println!(
82-
"Main OS Thread - {} -> {} ended: {:?}",
83-
"agent.online_cpu_mem()",
114+
"Main OS Thread - agent.online_cpu_mem() -> {} ended: {:?}",
84115
show,
85116
now.elapsed()
86117
);
87118

88119
println!("\nsleep 2 seconds ...\n");
89120
thread::sleep(std::time::Duration::from_secs(2));
121+
122+
let version = hc.version(default_ctx(), &health::CheckRequest::new());
123+
assert_eq!("mock.0.1", version.as_ref().unwrap().agent_version.as_str());
124+
assert_eq!("0.0.1", version.as_ref().unwrap().grpc_version.as_str());
90125
println!(
91-
"Main OS Thread - {} started: {:?}",
92-
"health.version()",
126+
"Main OS Thread - health.version() started: {:?}",
93127
now.elapsed()
94128
);
95129
println!(
96-
"Main OS Thread - {} -> {:?} ended: {:?}",
97-
"health.version()",
98-
hc.version(default_ctx(), &health::CheckRequest::new()),
130+
"Main OS Thread - health.version() -> {:?} ended: {:?}",
131+
version,
99132
now.elapsed()
100133
);
101134

example/protocols/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
//
33
// SPDX-License-Identifier: Apache-2.0
44
//
5-
5+
#[cfg(unix)]
66
pub mod asynchronous;
7-
pub mod sync;
7+
#[cfg(unix)]
88
pub use asynchronous as r#async;
9+
pub mod sync;

0 commit comments

Comments
 (0)