懸吊生平

使用 API 搭配停止運作的時,必須特別注意,以免遺失待處理的 FIDL 要求參照。部分未來的組合器 (例如 Abortablefuchsia_async::TimeoutExt) 會捨棄待處理的未來,導致 FIDL 要求的參照就會遭到捨棄 由於停止運作的取得方式通常是由通訊協定伺服器實作,因此如果在相同 Proxy 之前被捨棄,之後呼叫呼叫 get 方法可能無效。

為避免在使用這類組合時使 Proxy 失效,建議您採用 HangingGetStream 將懸掛式呼叫納入 stream 中:

// When you don't need to write down the type of the result, you can use a
// fn item, which has zero size and is statically dispatched when called.
let watch_foo_stream = HangingGetStream::new(proxy, FooWatcherProxy::watch_foo);
// Also you can use a capturing closure in that case.
let watch_bar_stream = HangingGetStream::new(proxy, |p| p.watch_bar(some_captured_var));

// If you do want to write down the type (for example when embedding this in
// another Future), you can achieve so by storing a fn pointer. A fn pointer
// can be obtained through coercion from a non-capturing closure or a fn item.
// That said, if you use a capturing closure, there is no way to name the type.
let watch_baz_stream: HangingGetStream<BazProxy, Baz> = HangingGetStream::new_with_fn_ptr(proxy, |p| p.watch_baz());

另一個方法是使用以下模式來建立串流。

fn hanging_get_stream(proxy: &FooProxy) -> impl futures::Stream<Item=Result<FooResult, fidl::Error>> + '_ {
    futures::stream::try_unfold(proxy, |proxy| {
       proxy.watch_foo().map_ok(move |watch_result| Some((watch_result, proxy)))
    })
}

捨棄 Stream::next 未來是安全的,因為這麼做不會造成基礎 FIDL 要求遭到捨棄。 如果串流在等待回應時遭到捨棄,系統會忽略回應。 如果 FIDL 伺服器同時不允許多個懸掛式獲取等候程序,這一點非常重要。