@@ -58,18 +58,57 @@ trait GenSpawnInstances {
5858 fiberA <- F .start(ParallelF .value(fa))
5959 fiberB <- F .start(ParallelF .value(fb))
6060
61+ // start a pair of supervisors to ensure that the opposite is canceled on error
62+ _ <- F start {
63+ fiberB.join flatMap {
64+ case Outcome .Succeeded (_) => F .unit
65+ case _ => fiberA.cancel
66+ }
67+ }
68+
69+ _ <- F start {
70+ fiberA.join flatMap {
71+ case Outcome .Succeeded (_) => F .unit
72+ case _ => fiberB.cancel
73+ }
74+ }
75+
6176 a <- F
6277 .onCancel(poll(fiberA.join), F .both(fiberA.cancel, fiberB.cancel).void)
6378 .flatMap[A ] {
64- case Outcome .Succeeded (fa) => fa
65- case Outcome .Errored (e) => fiberB.cancel *> F .raiseError(e)
66- case Outcome .Canceled () => fiberB.cancel *> poll(F .canceled *> F .never)
79+ case Outcome .Succeeded (fa) =>
80+ fa
81+
82+ case Outcome .Errored (e) =>
83+ fiberB.cancel *> F .raiseError(e)
84+
85+ case Outcome .Canceled () =>
86+ fiberB.cancel *> poll {
87+ fiberB.join flatMap {
88+ case Outcome .Succeeded (_) | Outcome .Canceled () =>
89+ F .canceled *> F .never
90+ case Outcome .Errored (e) =>
91+ F .raiseError(e)
92+ }
93+ }
6794 }
6895
6996 z <- F .onCancel(poll(fiberB.join), fiberB.cancel).flatMap[Z ] {
70- case Outcome .Succeeded (fb) => fb.map(b => f(a, b))
71- case Outcome .Errored (e) => F .raiseError(e)
72- case Outcome .Canceled () => poll(F .canceled *> F .never)
97+ case Outcome .Succeeded (fb) =>
98+ fb.map(b => f(a, b))
99+
100+ case Outcome .Errored (e) =>
101+ F .raiseError(e)
102+
103+ case Outcome .Canceled () =>
104+ poll {
105+ fiberA.join flatMap {
106+ case Outcome .Succeeded (_) | Outcome .Canceled () =>
107+ F .canceled *> F .never
108+ case Outcome .Errored (e) =>
109+ F .raiseError(e)
110+ }
111+ }
73112 }
74113 } yield z
75114 }
@@ -84,18 +123,57 @@ trait GenSpawnInstances {
84123 fiberA <- F .start(ParallelF .value(fa))
85124 fiberB <- F .start(ParallelF .value(fb.value))
86125
126+ // start a pair of supervisors to ensure that the opposite is canceled on error
127+ _ <- F start {
128+ fiberB.join flatMap {
129+ case Outcome .Succeeded (_) => F .unit
130+ case _ => fiberA.cancel
131+ }
132+ }
133+
134+ _ <- F start {
135+ fiberA.join flatMap {
136+ case Outcome .Succeeded (_) => F .unit
137+ case _ => fiberB.cancel
138+ }
139+ }
140+
87141 a <- F
88142 .onCancel(poll(fiberA.join), F .both(fiberA.cancel, fiberB.cancel).void)
89143 .flatMap[A ] {
90- case Outcome .Succeeded (fa) => fa
91- case Outcome .Errored (e) => fiberB.cancel *> F .raiseError(e)
92- case Outcome .Canceled () => fiberB.cancel *> poll(F .canceled *> F .never)
144+ case Outcome .Succeeded (fa) =>
145+ fa
146+
147+ case Outcome .Errored (e) =>
148+ fiberB.cancel *> F .raiseError(e)
149+
150+ case Outcome .Canceled () =>
151+ fiberB.cancel *> poll {
152+ fiberB.join flatMap {
153+ case Outcome .Succeeded (_) | Outcome .Canceled () =>
154+ F .canceled *> F .never
155+ case Outcome .Errored (e) =>
156+ F .raiseError(e)
157+ }
158+ }
93159 }
94160
95161 z <- F .onCancel(poll(fiberB.join), fiberB.cancel).flatMap[Z ] {
96- case Outcome .Succeeded (fb) => fb.map(b => f(a, b))
97- case Outcome .Errored (e) => F .raiseError(e)
98- case Outcome .Canceled () => poll(F .canceled *> F .never)
162+ case Outcome .Succeeded (fb) =>
163+ fb.map(b => f(a, b))
164+
165+ case Outcome .Errored (e) =>
166+ F .raiseError(e)
167+
168+ case Outcome .Canceled () =>
169+ poll {
170+ fiberA.join flatMap {
171+ case Outcome .Succeeded (_) | Outcome .Canceled () =>
172+ F .canceled *> F .never
173+ case Outcome .Errored (e) =>
174+ F .raiseError(e)
175+ }
176+ }
99177 }
100178 } yield z
101179 }
0 commit comments