✨ async channel
This commit is contained in:
parent
f904603a8d
commit
060209827f
5 changed files with 78 additions and 561 deletions
|
@ -26,7 +26,7 @@ pub static CONFIG: OnceCell<Config> = OnceCell::const_new();
|
|||
pub static MQTT: OnceCell<AsyncClient> = OnceCell::const_new();
|
||||
|
||||
pub static ONLINE: OnceCell<DashMap<String, chrono::DateTime<chrono::Utc>>> = OnceCell::const_new();
|
||||
pub static DISPATCH: OnceCell<DashMap<String, crossbeam::channel::Sender<ServerResponse>>> =
|
||||
pub static DISPATCH: OnceCell<DashMap<String, tokio::sync::oneshot::Sender<ServerResponse>>> =
|
||||
OnceCell::const_new();
|
||||
|
||||
fn generate_token() -> String {
|
||||
|
|
|
@ -44,12 +44,17 @@ pub async fn handle_mqtt(topic: String, data: Vec<u8>) {
|
|||
let resp: ServerResponse = serde_json::from_slice(&dec.payload).unwrap();
|
||||
log::info!("Got response {:?}", resp);
|
||||
|
||||
let entry = crate::DISPATCH
|
||||
let (id, entry) = crate::DISPATCH
|
||||
.get()
|
||||
.unwrap()
|
||||
.get(&resp.id.to_string())
|
||||
.remove(&resp.id.to_string())
|
||||
.unwrap();
|
||||
entry.send(resp);
|
||||
|
||||
if entry.send(resp).is_err() {
|
||||
log::error!(
|
||||
"Could not send back response for action {id}. Probably due to timeout"
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -57,13 +62,16 @@ pub async fn handle_mqtt(topic: String, data: Vec<u8>) {
|
|||
|
||||
pub struct TaskWaiter {
|
||||
pub id: ulid::Ulid,
|
||||
pub recv: crossbeam::channel::Receiver<ServerResponse>,
|
||||
pub recv: tokio::sync::oneshot::Receiver<ServerResponse>,
|
||||
}
|
||||
|
||||
impl TaskWaiter {
|
||||
pub async fn wait_for(&self, timeout: std::time::Duration) -> Option<ServerResponse> {
|
||||
// TODO tokio spawn blocking?
|
||||
self.recv.recv_timeout(timeout).ok()
|
||||
pub async fn wait_for(self, timeout: std::time::Duration) -> Option<ServerResponse> {
|
||||
if let Ok(in_time) = tokio::time::timeout(timeout, self.recv).await {
|
||||
return in_time.ok();
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +97,7 @@ pub async fn send_msg(
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let (sender, recv) = crossbeam::channel::bounded(100);
|
||||
let (sender, recv) = tokio::sync::oneshot::channel();
|
||||
crate::DISPATCH
|
||||
.get()
|
||||
.unwrap()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{io::Write, path::PathBuf};
|
||||
|
||||
use owl::{Deserialize, Serialize};
|
||||
use sheepd::{DeviceList, LoginParam, ShellResponse};
|
||||
|
@ -18,6 +18,21 @@ pub fn api_call<T: Serialize + for<'a> Deserialize<'a>, I: Serialize>(
|
|||
res
|
||||
}
|
||||
|
||||
pub fn api_call_post_auth<T: Serialize + for<'a> Deserialize<'a>, I: Serialize>(
|
||||
server: &str,
|
||||
path: &str,
|
||||
token: &str,
|
||||
data: I,
|
||||
) -> crate::api::Result<T> {
|
||||
let url = format!("{}/{path}", domain(server));
|
||||
let mut res = ureq::post(url)
|
||||
.header("Authorization", format!("Bearer {token}"))
|
||||
.send_json(data)
|
||||
.unwrap();
|
||||
let res: crate::api::Result<T> = res.body_mut().read_json().unwrap();
|
||||
res
|
||||
}
|
||||
|
||||
pub fn api_call_get<T: Serialize + for<'a> Deserialize<'a>>(
|
||||
server: &str,
|
||||
path: &str,
|
||||
|
@ -94,6 +109,7 @@ pub fn interactive_shell(arg: ShellCommand) {
|
|||
|
||||
loop {
|
||||
print!("{} [{}]: {cwd} $ ", machine.hostname, machine.id);
|
||||
std::io::stdout().flush().unwrap();
|
||||
let mut read = String::new();
|
||||
std::io::stdin().read_line(&mut read).unwrap();
|
||||
if read == "exit" {
|
||||
|
@ -106,9 +122,10 @@ pub fn interactive_shell(arg: ShellCommand) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let res = api_call::<ShellResponse, _>(
|
||||
let res = api_call_post_auth::<ShellResponse, _>(
|
||||
&conf.home,
|
||||
&format!("device/{}/shell", machine.id),
|
||||
&conf.token,
|
||||
ShellParam {
|
||||
cmd: read.clone(),
|
||||
cwd: cwd.clone(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue