Skip to content

Commit efce46e

Browse files
authored
Merge pull request #65 from CoLearn-Dev/po_heartbeat
Protocol operator: add heartbeat, add consumption mark
2 parents cce2074 + 540e745 commit efce46e

File tree

7 files changed

+102
-52
lines changed

7 files changed

+102
-52
lines changed

.github/workflows/check.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,15 @@ jobs:
4545
with:
4646
submodules: recursive
4747
- name: Install Rust
48-
uses: actions-rs/toolchain@v1
49-
with:
50-
toolchain: stable
51-
components: rustfmt, clippy
48+
run: |
49+
rustup toolchain install stable --no-self-update --component rustfmt --component clippy
50+
rustup default stable
51+
- name: Install protobuf
52+
if: ${{ startsWith(matrix.ci_image, 'ubuntu') }}
53+
run: sudo apt update && sudo apt install protobuf-compiler -y
54+
- name: Install protobuf(macos)
55+
if: ${{ startsWith(matrix.ci_image, 'macos') }}
56+
run: brew install protobuf
5257
- name: Check
5358
if: ${{ startsWith(matrix.ci_image, 'ubuntu') }} # skip check in macos because it is slow
5459
run: cargo check --release

.github/workflows/publish_to_crates.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ jobs:
1717
submodules: recursive
1818
ssh-key: ${{ secrets.SSH_KEY }}
1919
- name: Install Rust
20-
uses: actions-rs/toolchain@v1
21-
with:
22-
toolchain: stable
20+
run: |
21+
rustup toolchain install stable --no-self-update
22+
rustup default stable
23+
- name: Install protobuf
24+
run: sudo apt update && sudo apt install protobuf-compiler -y
2325
- name: Publish
2426
env:
2527
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

Cargo.toml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "colink"
3-
version = "0.3.9"
3+
version = "0.3.10"
44
edition = "2021"
55
description = "CoLink Rust SDK"
66
license = "MIT"
@@ -14,33 +14,33 @@ async-recursion = { version = "1.0", optional = true }
1414
async-trait = "0.1"
1515
base64 = "0.13"
1616
chrono = "0.4"
17-
clap = { version = "4.0", features = ["derive", "env"] }
18-
futures-lite = "1.12"
17+
clap = { version = "4.3", features = ["derive", "env"] }
18+
futures-lite = "1.13"
1919
hyper = { version = "0.14", optional = true }
20-
hyper-rustls = { version = "0.23", optional = true }
20+
hyper-rustls = { version = "0.24", optional = true }
2121
jsonwebtoken = { version = "7.2", optional = true }
22-
lapin = "2.1"
23-
prost = "0.10"
22+
lapin = "2.2"
23+
prost = "0.11"
2424
rand = { version = "0.8", features = ["std_rng"] }
2525
rcgen = { version = "0.10", optional = true }
2626
rdbc2 = { version = "0.2.2", optional = true }
27-
redis = { version = "0.22", features = ["tokio-comp"] }
27+
redis = { version = "0.23", features = ["tokio-rustls-comp"] }
2828
reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-native-roots"], optional = true }
29-
secp256k1 = { version = "0.25", features = ["rand-std"] }
29+
secp256k1 = { version = "0.27", features = ["rand-std"] }
3030
serde = { version = "1.0", features = ["derive"] }
3131
serde_json = "1.0"
3232
sha2 = "0.10"
33-
tokio = { version = "1.24", features = ["macros", "rt-multi-thread", "rt", "fs"] }
34-
tokio-rustls = { version = "0.23", optional = true }
35-
tonic = { version = "0.7", features = ["tls", "tls-roots"] }
33+
tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "rt", "fs"] }
34+
tokio-rustls = { version = "0.24", optional = true }
35+
tonic = { version = "0.9", features = ["tls", "tls-roots"] }
3636
tracing = "0.1"
3737
tracing-subscriber = "0.2"
3838
url = "2.2"
3939
uuid = { version = "0.8", features = ["v4"] }
4040

4141
[build-dependencies]
42-
prost-build = "0.10"
43-
tonic-build = "0.7"
42+
prost-build = "0.11"
43+
tonic-build = "0.9"
4444

4545
[features]
4646
default = ["extensions", "remote_storage", "variable_transfer", "registry", "policy_module", "instant_server", "storage_macro"]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ CoLink SDK helps both application and protocol developers access the functionali
99
Add this to your Cargo.toml:
1010
```toml
1111
[dependencies]
12-
colink = "0.3.9"
12+
colink = "0.3.10"
1313
```
1414

1515
Enable more features in your Cargo.toml
1616
```
1717
# if you use storage macro dbc
18-
colink = { version = "0.3.9", features = ["storage_macro_dbc"] }
18+
colink = { version = "0.3.10", features = ["storage_macro_dbc"] }
1919
```
2020

2121
## Getting Started

src/extensions/variable_transfer/p2p_inbox.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl VTInboxServer {
122122
let graceful = server.with_graceful_shutdown(async move {
123123
rx.recv().await;
124124
});
125-
tokio::spawn(async { graceful.await });
125+
tokio::spawn(graceful);
126126
Self {
127127
port,
128128
jwt_secret,

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ pub use application::{
1010
};
1111
pub use colink_proto::*;
1212
pub use protocol::{
13-
CoLinkProtocol, ProtocolEntry, _colink_parse_args, _protocol_start, async_trait,
13+
CoLinkProtocol, CoLinkProtocolCommandLineArgs, ProtocolEntry, _colink_parse_args,
14+
_protocol_start, async_trait,
1415
};
1516
pub mod extensions;
1617
pub mod utils;

src/protocol.rs

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ pub struct CoLinkProtocol {
2525
protocol_and_role: String,
2626
cl: CoLink,
2727
user_func: Box<dyn ProtocolEntry>,
28-
vt_public_addr: Option<String>,
28+
args: CoLinkProtocolCommandLineArgs,
2929
}
3030

3131
impl CoLinkProtocol {
3232
pub fn new(
3333
protocol_and_role: &str,
3434
cl: CoLink,
3535
user_func: Box<dyn ProtocolEntry>,
36-
vt_public_addr: Option<String>,
36+
args: CoLinkProtocolCommandLineArgs,
3737
) -> Self {
3838
Self {
3939
protocol_and_role: protocol_and_role.to_string(),
4040
cl,
4141
user_func,
42-
vt_public_addr,
42+
args,
4343
}
4444
}
4545

@@ -78,11 +78,20 @@ impl CoLinkProtocol {
7878
{
7979
cl.vt_p2p_ctx =
8080
Arc::new(crate::extensions::variable_transfer::p2p_inbox::VtP2pCtx {
81-
public_addr: self.vt_public_addr.clone(),
81+
public_addr: self.args.vt_public_addr.clone(),
8282
..Default::default()
8383
});
8484
}
8585
let cl_clone = cl.clone();
86+
let instance_id = match &self.args.instance_id {
87+
Some(instance_id) => instance_id,
88+
None => "anonymous",
89+
};
90+
cl.update_entry(
91+
&format!("_internal:task_po_mapping:{}", task.task_id),
92+
instance_id.as_bytes(),
93+
)
94+
.await?;
8695
match self
8796
.user_func
8897
.start(cl, task.protocol_param, task.participants)
@@ -170,8 +179,7 @@ impl CoLinkProtocol {
170179
pub fn _protocol_start(
171180
cl: CoLink,
172181
user_funcs: HashMap<String, Box<dyn ProtocolEntry + Send + Sync>>,
173-
keep_alive_when_disconnect: bool,
174-
vt_public_addr: Option<String>,
182+
args: CoLinkProtocolCommandLineArgs,
175183
) -> Result<(), Error> {
176184
let mut operator_funcs: HashMap<String, Box<dyn ProtocolEntry + Send + Sync>> = HashMap::new();
177185
let mut protocols = HashSet::new();
@@ -233,14 +241,14 @@ pub fn _protocol_start(
233241
let mut threads = vec![];
234242
for (protocol_and_role, user_func) in operator_funcs {
235243
let cl = cl.clone();
236-
let vt_public_addr = vt_public_addr.clone();
244+
let args = args.clone();
237245
threads.push(thread::spawn(|| {
238246
tokio::runtime::Builder::new_multi_thread()
239247
.enable_all()
240248
.build()
241249
.unwrap()
242250
.block_on(async move {
243-
match CoLinkProtocol::new(&protocol_and_role, cl, user_func, vt_public_addr)
251+
match CoLinkProtocol::new(&protocol_and_role, cl, user_func, args)
244252
.start()
245253
.await
246254
{
@@ -250,7 +258,36 @@ pub fn _protocol_start(
250258
});
251259
}));
252260
}
253-
if keep_alive_when_disconnect {
261+
if args.enable_heartbeat {
262+
let cl = cl.clone();
263+
if let Some(instance_id) = args.instance_id {
264+
thread::spawn(|| {
265+
tokio::runtime::Builder::new_multi_thread()
266+
.enable_all()
267+
.build()
268+
.unwrap()
269+
.block_on(async move {
270+
loop {
271+
let timestamp = chrono::Utc::now().timestamp_nanos();
272+
let _ = cl
273+
.update_entry(
274+
&format!(
275+
"_internal:protocol_operator_instances:{}:heartbeat",
276+
instance_id
277+
),
278+
&timestamp.to_le_bytes(),
279+
)
280+
.await;
281+
let st = rand::thread_rng().gen_range(32..64);
282+
tokio::time::sleep(tokio::time::Duration::from_secs(st)).await;
283+
}
284+
});
285+
});
286+
} else {
287+
return Err("Cannot find instance_id while heartbeat is enabled, please specify instance_id to enable this functionality.".into());
288+
}
289+
}
290+
if args.keep_alive_when_disconnect {
254291
for thread in threads {
255292
thread.join().unwrap();
256293
}
@@ -282,9 +319,9 @@ pub fn _protocol_start(
282319
Ok(())
283320
}
284321

285-
#[derive(Debug, Parser)]
322+
#[derive(Debug, Clone, Default, Parser)]
286323
#[command(name = "CoLink-SDK", about = "CoLink-SDK")]
287-
pub struct CommandLineArgs {
324+
pub struct CoLinkProtocolCommandLineArgs {
288325
/// Address of CoLink server
289326
#[arg(short, long, env = "COLINK_CORE_ADDR")]
290327
pub addr: String,
@@ -293,6 +330,10 @@ pub struct CommandLineArgs {
293330
#[arg(short, long, env = "COLINK_JWT")]
294331
pub jwt: String,
295332

333+
/// Path to CA certificate.
334+
#[arg(long, env = "COLINK_INSTANCE_ID")]
335+
pub instance_id: Option<String>,
336+
296337
/// Path to CA certificate.
297338
#[arg(long, env = "COLINK_CA_CERT")]
298339
pub ca: Option<String>,
@@ -309,37 +350,34 @@ pub struct CommandLineArgs {
309350
#[arg(long, env = "COLINK_KEEP_ALIVE_WHEN_DISCONNECT")]
310351
pub keep_alive_when_disconnect: bool,
311352

353+
/// Enable heartbeat.
354+
#[arg(long, env = "COLINK_ENABLE_HEARTBEAT")]
355+
pub enable_heartbeat: bool,
356+
312357
/// Public address for the variable transfer inbox.
313358
#[arg(long, env = "COLINK_VT_PUBLIC_ADDR")]
314359
pub vt_public_addr: Option<String>,
315360
}
316361

317-
pub fn _colink_parse_args() -> (CoLink, bool, Option<String>) {
362+
pub fn _colink_parse_args() -> (CoLink, CoLinkProtocolCommandLineArgs) {
318363
tracing_subscriber::fmt::init();
319-
let CommandLineArgs {
320-
addr,
321-
jwt,
322-
ca,
323-
cert,
324-
key,
325-
keep_alive_when_disconnect,
326-
vt_public_addr,
327-
} = CommandLineArgs::parse();
328-
let mut cl = CoLink::new(&addr, &jwt);
329-
if let Some(ca) = ca {
364+
let args = CoLinkProtocolCommandLineArgs::parse();
365+
let args_clone = args.clone();
366+
let mut cl = CoLink::new(&args.addr, &args.jwt);
367+
if let Some(ca) = args.ca {
330368
cl = cl.ca_certificate(&ca);
331369
}
332-
if let (Some(cert), Some(key)) = (cert, key) {
370+
if let (Some(cert), Some(key)) = (args.cert, args.key) {
333371
cl = cl.identity(&cert, &key);
334372
}
335-
(cl, keep_alive_when_disconnect, vt_public_addr)
373+
(cl, args_clone)
336374
}
337375

338376
#[macro_export]
339377
macro_rules! protocol_start {
340378
( $( $x:expr ),* ) => {
341379
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
342-
let (cl, keep_alive_when_disconnect, vt_public_addr) = colink::_colink_parse_args();
380+
let (cl, args) = colink::_colink_parse_args();
343381

344382
let mut user_funcs: std::collections::HashMap<
345383
String,
@@ -349,7 +387,7 @@ macro_rules! protocol_start {
349387
user_funcs.insert($x.0.to_string(), Box::new($x.1));
350388
)*
351389

352-
colink::_protocol_start(cl, user_funcs, keep_alive_when_disconnect, vt_public_addr)?;
390+
colink::_protocol_start(cl, user_funcs, args)?;
353391

354392
Ok(())
355393
}
@@ -368,8 +406,12 @@ macro_rules! protocol_attach {
368406
$(
369407
user_funcs.insert($x.0.to_string(), Box::new($x.1));
370408
)*
409+
let args = colink::CoLinkProtocolCommandLineArgs {
410+
vt_public_addr: Some("127.0.0.1".to_string()),
411+
..Default::default()
412+
};
371413
std::thread::spawn(|| {
372-
colink::_protocol_start(cl, user_funcs, false, Some("127.0.0.1".to_string()))?;
414+
colink::_protocol_start(cl, user_funcs, args)?;
373415
Ok::<(), Box<dyn std::error::Error + Send + Sync + 'static>>(())
374416
});
375417
}

0 commit comments

Comments
 (0)