use crate::error::Error; use crate::error_event::ErrorEventData; use crate::event::{Event, EventType}; use crate::ipc::stream_emitter::emit_metadata::EmitMetadata; use crate::payload::IntoPayload; use crate::{error, poll_unwrap}; use futures::future; use futures::future::Either; use std::future::Future; use std::pin::Pin; use std::task::Poll; use std::time::Duration; /// A metadata object returned after waiting for a reply to an event /// This object needs to be awaited for to get the actual reply pub struct EmitMetadataWithResponse { pub(crate) timeout: Option, pub(crate) fut: Option> + Send + Sync>>>, pub(crate) emit_metadata: Option>, } impl EmitMetadataWithResponse

{ /// Sets a timeout for awaiting replies to this emitted event #[inline] pub fn with_timeout(mut self, timeout: Duration) -> Self { self.timeout = Some(timeout); self } } impl Unpin for EmitMetadataWithResponse

{} impl Future for EmitMetadataWithResponse

{ type Output = error::Result; fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { if self.fut.is_none() { let mut emit_metadata = poll_unwrap!(self.emit_metadata.take()); let ctx = poll_unwrap!(emit_metadata .event_metadata .as_ref() .and_then(|m| m.ctx.clone())); let timeout = self .timeout .clone() .unwrap_or(ctx.default_reply_timeout.clone()); let event_id = match poll_unwrap!(emit_metadata.event_metadata.as_mut()).get_event() { Ok(e) => e.id(), Err(e) => { return Poll::Ready(Err(e)); } }; self.fut = Some(Box::pin(async move { let tx = ctx.register_reply_listener(event_id).await?; emit_metadata.await?; let result = future::select(Box::pin(tx), Box::pin(tokio::time::sleep(timeout))).await; let reply = match result { Either::Left((tx_result, _)) => Ok(tx_result?), Either::Right(_) => { let mut listeners = ctx.reply_listeners.lock().await; listeners.remove(&event_id); Err(Error::Timeout) } }?; if reply.event_type() == EventType::Error { Err(reply.payload::()?.into()) } else { Ok(reply) } })) } self.fut.as_mut().unwrap().as_mut().poll(cx) } }