懸吊生平

使用具有等待取得的 API 時,必須小心謹慎 以避免遺失待處理 FIDL 要求的參照。未來期 我們結合了 Abortablefuchsia_async::TimeoutExt 將會捨棄待處理的未來, 因此,系統會捨棄對 FIDL 要求的參照。由於 停止運作的作業通常是由通訊協定伺服器以有狀態的方式實作 若是呼叫 hanging get 方法,則會失效於 已捨棄相同的 Proxy

為避免在使用這類合併器時使 Proxy 失效,採用以下模式: 使用stream HangingGetStream:

// 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 Future 安全無虞,因為這不會導致 未捨棄的基礎 FIDL 要求如果串流本身在等待 回應,就會被忽略。如果 FIDL 伺服器不允許 讓多名等待人員同時等待。