我正在阅读这段 Rust 代码,但我几乎没有能力理解所有互斥体和句柄的情况。为了让 Rust 诸神高兴,这一切都是多余的,而且这让他们很难专注于实际发生的事情。看一看:
#[tauri::command]
fn spawn(param: String, window: Window<Wry>) {
let window_arc = Arc::new(Mutex::new(window));
// Spawn bin
let (mut rx, child) = tauri::api::process::Command::new_sidecar("bin")
.expect("failed to create binary command")
.args([param])
.spawn()
.expect("Failed to spawn sidecar");
let child_arc = Arc::new(Mutex::new(child));
// Handle data from bin
let window = window_arc.clone();
let (handle, mut handle_rx) = broadcast::channel(1);
let handle_arc = Arc::new(Mutex::new(handle));
tauri::async_runtime::spawn(async move {
loop {
tokio::select! {
_ = handle_rx.recv() => {
return;
}
Some(event) = rx.recv() => {
if let CommandEvent::Stdout(line) = &event {
let data = decode_and_xor(line.clone());
println!("Data from bin: {}", data);
window.lock().unwrap().emit("from_bin", data).expect("failed to emit message");
}
if let CommandEvent::Stderr(line) = &event {
println!("Fatal error bin: {}", &line);
window.lock().unwrap().emit("bin_fatal_error", line).expect("failed to emit message");
}
}
}
;
}
});
let window = window_arc.clone();
let window_cc = window.clone();
window_cc.lock().unwrap().listen("kill_bin", move |event| {
let handle = handle_arc.clone();
handle.lock().unwrap().send(true).unwrap();
window.lock().unwrap().unlisten(event.id());
});
// Handle data to bin
let window = window_arc.clone();
tauri::async_runtime::spawn(async move {
let child_clone = child_arc.clone();
let (handle, handle_rx) = broadcast::channel(1);
let handle_rx_arc = Arc::new(Mutex::new(handle_rx));
let handle_arc = Arc::new(Mutex::new(handle));
let window_c = window.clone();
window.lock().unwrap().listen("to_bin", move |event| {
let handle_rx = handle_rx_arc.clone();
if handle_rx.lock().unwrap().try_recv().is_ok() {
window_c.lock().unwrap().unlisten(event.id());
return;
}
// Send data to bin
let payload = String::from(event.payload().unwrap());
let encrypted = xor_and_encode(payload) + "\n";
println!("Data to send: {}", event.payload().unwrap());
child_clone.clone().lock().unwrap().write(encrypted.as_bytes()).expect("could not write to child");
});
let window_c = window.clone();
window.lock().unwrap().listen("kill_bin", move |event| {
let handle = handle_arc.clone();
handle.lock().unwrap().send(true).unwrap();
window_c.lock().unwrap().unlisten(event.id());
});
});
}
Run Code Online (Sandbox Code Playgroud)
所有这些弧线、互斥体和克隆都是必要的吗?我该如何以 Rust 惯用的方式清理这个问题,以便更容易地了解发生了什么?
所有这些弧线、互斥体和克隆都是必要的吗?
可能不是,您似乎过度克隆并重新包装并发结构,但您必须查看特定的 API
例如,假设broascast::channel
Tokio 是为并发使用而设计的(这就是重点),因此发送方被设计为可克隆(对于多个生产者),并且您可以根据需要从发送方创建尽可能多的接收方。
不需要用弧形包裹,特别是不需要用锁来保护它们,它们被设计为按原样工作。
此外,在这种情况下,它甚至没有必要,因为您只有一个发送者任务和一个接收者任务,两者都不是共享的。使用它们时也不需要克隆它们。所以例如
let handle_arc = Arc::new(Mutex::new(handle));
[...]
window_cc.lock().unwrap().listen("kill_bin", move |event| {
let handle = handle_arc.clone();
handle.lock().unwrap().send(true).unwrap();
window.lock().unwrap().unlisten(event.id());
});
Run Code Online (Sandbox Code Playgroud)
我很确定可以
window_cc.lock().unwrap().listen("kill_bin", move |event| {
handle.send(true).unwrap();
window.lock().unwrap().unlisten(event.id());
});
Run Code Online (Sandbox Code Playgroud)
这就是封口里面的move
内容handle
,然后发送出去。Sender
内部是可变的,因此它不需要锁定来发送事件(这宁愿破坏这一点)。
归档时间: |
|
查看次数: |
644 次 |
最近记录: |