@@ -545,25 +545,24 @@ final class Stream[+F[_], +O] private[fs2] (private val free: FreeC[F, O, Unit])
545
545
)(implicit F : Concurrent [F2 ]): Stream [F2 , O ] = {
546
546
val fstream : F2 [Stream [F2 , O ]] = for {
547
547
interrupt <- Deferred [F2 , Unit ]
548
- doneR <- Deferred [F2 , Either [Throwable , Unit ]]
548
+ backResult <- Deferred [F2 , Either [Throwable , Unit ]]
549
549
} yield {
550
- def runR : F2 [Unit ] =
551
- that.interruptWhen(interrupt.get.attempt).compile.drain.attempt.flatMap { r =>
552
- doneR.complete(r) >> {
553
- if (r.isLeft)
554
- interrupt
555
- .complete(())
556
- .attempt
557
- .void // interrupt only if this failed otherwise give change to `this` to finalize
558
- else F .unit
559
- }
560
- }
550
+ def watch [A ](str : Stream [F2 , A ]) = str.interruptWhen(interrupt.get.attempt)
551
+
552
+ val compileBack : F2 [Unit ] = watch(that).compile.drain.guaranteeCase {
553
+ // Pass the result of backstream completion in the backResult deferred.
554
+ // If result of back-stream was failed, interrupt fore. Otherwise, let it be
555
+ case ExitCase .Error (t) =>
556
+ backResult.complete(Left (t)).attempt >> interrupt.complete(()).handleError(_ => ())
557
+ case _ => backResult.complete(Right (())).handleError(_ => ())
558
+ }
561
559
562
560
// stop background process but await for it to finalise with a result
563
- val stopBack : F2 [Unit ] = interrupt.complete(()).attempt >> doneR.get.flatMap(F .fromEither)
561
+ // We use F.fromEither to bring errors from the back into the fore
562
+ val stopBack : F2 [Unit ] =
563
+ interrupt.complete(()).attempt >> backResult.get.flatMap(F .fromEither)
564
564
565
- Stream .bracket(F .start(runR))(_ => stopBack) >>
566
- this .interruptWhen(interrupt.get.attempt)
565
+ Stream .bracket(F .start(compileBack))(_ => stopBack) >> watch(this )
567
566
}
568
567
569
568
Stream .eval(fstream).flatten
0 commit comments