multiple streams on one connection
This commit is contained in:
parent
eae2aa210f
commit
e48b9b0fef
1223
daemon-mock/Cargo.lock
generated
Normal file
1223
daemon-mock/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,3 +4,14 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.94"
|
||||
env_logger = "0.11.6"
|
||||
log = "0.4.22"
|
||||
prost = "0.13.4"
|
||||
prost-types = "0.13.4"
|
||||
tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1.17"
|
||||
tonic = "0.12"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12"
|
||||
|
109
daemon-mock/brain.proto
Normal file
109
daemon-mock/brain.proto
Normal file
@ -0,0 +1,109 @@
|
||||
syntax = "proto3";
|
||||
package brain;
|
||||
|
||||
message Empty {
|
||||
}
|
||||
|
||||
message NodePubkey {
|
||||
string node_pubkey = 1;
|
||||
}
|
||||
|
||||
message RegisterNodeRequest {
|
||||
string node_pubkey = 1;
|
||||
string owner_pubkey = 2;
|
||||
string ip = 3;
|
||||
string country = 4;
|
||||
string city = 5;
|
||||
uint32 avail_ports = 6;
|
||||
uint32 avail_ipv4 = 7;
|
||||
uint32 avail_ipv6 = 8;
|
||||
uint32 avail_vcpus = 9;
|
||||
uint32 avail_memory_mb = 10;
|
||||
uint32 avail_storage_gb = 11;
|
||||
uint32 max_ports_per_vm = 12;
|
||||
}
|
||||
|
||||
message NewVMRequest {
|
||||
string uuid = 1; // UUID is empty when CLI sends request; brain sets UUID
|
||||
string hostname = 2;
|
||||
string admin_pubkey = 3;
|
||||
string node_pubkey = 4;
|
||||
repeated uint32 extra_ports = 5;
|
||||
bool public_ipv4 = 6;
|
||||
bool public_ipv6 = 7;
|
||||
uint32 disk_size_gb = 8;
|
||||
uint32 vcpus = 9;
|
||||
uint32 memory_mb = 10;
|
||||
string kernel_url = 11;
|
||||
string kernel_sha = 12;
|
||||
string dtrfs_url = 13;
|
||||
string dtrfs_sha = 14;
|
||||
}
|
||||
|
||||
message VMContract {
|
||||
string uuid = 1;
|
||||
string hostname = 2;
|
||||
string admin_pubkey = 3;
|
||||
string node_pubkey = 4;
|
||||
repeated uint32 exposed_ports = 5;
|
||||
string public_ipv4 = 6;
|
||||
string public_ipv6 = 7;
|
||||
uint32 disk_size_gb = 8;
|
||||
uint32 vcpus = 9;
|
||||
uint32 memory_mb = 10;
|
||||
string kernel_sha = 11;
|
||||
string dtrfs_sha = 12;
|
||||
string created_at = 13;
|
||||
}
|
||||
|
||||
message ListVMContractsReq {
|
||||
string admin_pubkey = 1;
|
||||
string node_pubkey = 2;
|
||||
}
|
||||
|
||||
message NewVMConfirmation {
|
||||
string uuid = 1;
|
||||
repeated uint32 exposed_ports = 2;
|
||||
string public_ipv4 = 3;
|
||||
string public_ipv6 = 4;
|
||||
string error = 5;
|
||||
}
|
||||
|
||||
message DeletedVMUpdate {
|
||||
string uuid = 1;
|
||||
}
|
||||
|
||||
service BrainDaemonService {
|
||||
rpc RegisterNode (RegisterNodeRequest) returns (Empty);
|
||||
rpc GetNewVMReqs (NodePubkey) returns (stream NewVMRequest);
|
||||
rpc SendVMConfirmations (stream NewVMConfirmation) returns (Empty);
|
||||
rpc DeletedVMUpdates (NodePubkey) returns (stream DeletedVMUpdate);
|
||||
rpc ListVMContracts (ListVMContractsReq) returns (stream VMContract);
|
||||
}
|
||||
|
||||
message NodeFilters {
|
||||
uint32 free_ports = 1;
|
||||
bool offers_ipv4 = 2;
|
||||
bool offers_ipv6 = 3;
|
||||
uint32 vcpus = 4;
|
||||
uint32 memory_mb = 5;
|
||||
uint32 storage_gb = 6;
|
||||
string country = 7;
|
||||
}
|
||||
|
||||
message NodeListResp {
|
||||
string node_pubkey = 1;
|
||||
string country = 2;
|
||||
string city = 3;
|
||||
string ip = 4; // required for latency test
|
||||
uint32 server_rating = 5;
|
||||
uint32 provider_rating = 6;
|
||||
}
|
||||
|
||||
service BrainCliService {
|
||||
rpc CreateVMContract (NewVMRequest) returns (NewVMConfirmation);
|
||||
rpc ListVMContracts (ListVMContractsReq) returns (stream VMContract);
|
||||
rpc ListNodes (NodeFilters) returns (stream NodeListResp);
|
||||
rpc DeleteVM (DeletedVMUpdate) returns (Empty);
|
||||
}
|
||||
|
6
daemon-mock/build.rs
Normal file
6
daemon-mock/build.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
tonic_build::configure()
|
||||
.build_server(true)
|
||||
.compile_protos(&["brain.proto"], &["proto"])
|
||||
.unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
|
||||
}
|
@ -1,3 +1,78 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
#![allow(dead_code)]
|
||||
pub mod brain {
|
||||
tonic::include_proto!("brain");
|
||||
}
|
||||
|
||||
use anyhow::Result;
|
||||
use brain::{
|
||||
brain_daemon_service_client::BrainDaemonServiceClient, NewVmConfirmation, NewVmRequest,
|
||||
NodePubkey,
|
||||
};
|
||||
use log::{error, debug, warn, info};
|
||||
use tokio::time::{sleep, Duration};
|
||||
use tokio::{sync::mpsc::Receiver, sync::mpsc::Sender, task::JoinSet};
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tokio_stream::StreamExt;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
async fn listen_for_new_vm_reqs(
|
||||
mut client: BrainDaemonServiceClient<Channel>,
|
||||
tx: Sender<NewVmRequest>,
|
||||
) -> Result<()> {
|
||||
let node_pubkey = "somePublicKey".to_string();
|
||||
let mut grpc_stream = client
|
||||
.get_new_vm_reqs(NodePubkey { node_pubkey })
|
||||
.await?
|
||||
.into_inner();
|
||||
while let Some(newvmreq) = grpc_stream.next().await {
|
||||
info!("Received new vm request: {newvmreq:?}");
|
||||
let _ = tx.send(newvmreq?).await;
|
||||
}
|
||||
debug!("listen_for_new_vm_reqs is about to exit");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_confirmations(
|
||||
mut client: BrainDaemonServiceClient<Channel>,
|
||||
rx: Receiver<NewVmConfirmation>,
|
||||
) -> Result<()> {
|
||||
let rx_stream = ReceiverStream::new(rx);
|
||||
client.send_vm_confirmations(rx_stream).await?;
|
||||
debug!("send_confirmations is about to exit");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn connect_and_run() -> Result<()> {
|
||||
let client = BrainDaemonServiceClient::connect("http://[::1]:31337").await?;
|
||||
let mut streaming_tasks = JoinSet::new();
|
||||
|
||||
let newvm_client = client.clone();
|
||||
let (tx, _newvm_rx) = tokio::sync::mpsc::channel(6);
|
||||
streaming_tasks.spawn(listen_for_new_vm_reqs(newvm_client, tx));
|
||||
|
||||
let confirm_client = client.clone();
|
||||
let (_confirm_tx, rx) = tokio::sync::mpsc::channel(6);
|
||||
streaming_tasks.spawn(send_confirmations(confirm_client, rx));
|
||||
|
||||
let task_output = streaming_tasks.join_next().await;
|
||||
warn!("One stream exited: {task_output:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn connection_wrapper() -> ! {
|
||||
loop {
|
||||
info!("Connecting to brain...");
|
||||
if let Err(e) = connect_and_run().await {
|
||||
error!("The connection broke: {e}");
|
||||
}
|
||||
sleep(Duration::from_secs(3)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
connection_wrapper().await;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user