diff --git a/update-engine/src/engine.rs b/update-engine/src/engine.rs index ca54f6f257..3da9696eff 100644 --- a/update-engine/src/engine.rs +++ b/update-engine/src/engine.rs @@ -71,7 +71,7 @@ impl<'a, S: StepSpec> UpdateEngine<'a, S> { step_fn: F, ) -> NewStep<'_, 'a, S, T> where - F: FnOnce(StepContext) -> Fut + 'a, + F: FnOnce(StepContext) -> Fut + Send + 'a, Fut: Future, S::Error>> + Send + 'a, T: Send + 'a, { @@ -254,7 +254,7 @@ impl<'engine, 'a, S: StepSpec> ComponentRegistrar<'engine, 'a, S> { step_fn: F, ) -> NewStep<'engine, 'a, S, T> where - F: FnOnce(StepContext) -> Fut + 'a, + F: FnOnce(StepContext) -> Fut + Send + 'a, Fut: Future, S::Error>> + Send + 'a, T: Send + 'a, { @@ -313,7 +313,7 @@ impl<'engine, 'a, S: StepSpec, T> NewStep<'engine, 'a, S, T> { /// be infallible, and will often just be synchronous code. pub fn with_metadata_fn(mut self, f: F) -> Self where - F: FnOnce(MetadataContext) -> Fut + 'a, + F: FnOnce(MetadataContext) -> Fut + Send + 'a, Fut: Future + Send + 'a, { self.metadata_fn = Some(DebugIgnore(Box::new(|cx| (f)(cx).boxed()))); @@ -518,6 +518,7 @@ type StepMetadataFn<'a, S> = Box< dyn FnOnce( MetadataContext, ) -> BoxFuture<'a, ::StepMetadata> + + Send + 'a, >; @@ -533,6 +534,7 @@ type StepExecFn<'a, S> = Box< StepContext, ) -> BoxFuture<'a, Result, ::Error>> + + Send + 'a, >; @@ -687,15 +689,22 @@ impl StepProgressReporter { self, error: &S::Error, ) -> Result<(), mpsc::error::SendError>> { - let error = error.as_error(); - let message = error.to_string(); - - let mut current = error; - let mut causes = vec![]; - while let Some(source) = current.source() { - causes.push(source.to_string()); - current = source; - } + // Stringify `error` into a message + list causes; this is written the + // way it is to avoid `error` potentially living across the `.await` + // below (which can cause lifetime issues in callers). + let (message, causes) = { + let error = error.as_error(); + let message = error.to_string(); + + let mut current = error; + let mut causes = vec![]; + while let Some(source) = current.source() { + causes.push(source.to_string()); + current = source; + } + + (message, causes) + }; self.sender .send(Event::Step(StepEvent {