@@ -1228,7 +1228,7 @@ sealed trait ZIO[-R, +E, +A]
1228
1228
* Returns a new scoped workflow that runs finalizers added to the scope of
1229
1229
* this workflow in parallel.
1230
1230
*/
1231
- final def parallelFinalizers (implicit trace : Trace ): ZIO [R with Scope , E , A ] =
1231
+ final def parallelFinalizers (implicit trace : Trace ): ZIO [R , E , A ] =
1232
1232
ZIO .parallelFinalizers(self)
1233
1233
1234
1234
/**
@@ -1858,7 +1858,7 @@ sealed trait ZIO[-R, +E, +A]
1858
1858
* has meaning if used within a scope where finalizers are being run in
1859
1859
* parallel.
1860
1860
*/
1861
- final def sequentialFinalizers (implicit trace : Trace ): ZIO [R with Scope , E , A ] =
1861
+ final def sequentialFinalizers (implicit trace : Trace ): ZIO [R , E , A ] =
1862
1862
ZIO .sequentialFinalizers(self)
1863
1863
1864
1864
/**
@@ -2538,20 +2538,21 @@ sealed trait ZIO[-R, +E, +A]
2538
2538
)
2539
2539
.forkDaemon
2540
2540
2541
- fork(self, false ).zip(fork(that, true )).flatMap { case (left, right) =>
2542
- restore(promise.await).foldCauseZIO(
2543
- cause =>
2544
- left.interruptFork *> right.interruptFork *>
2545
- left.await.zip(right.await).flatMap { case (left, right) =>
2546
- left.zipWith(right)(f, _ && _) match {
2547
- case Exit .Failure (causes) => ZIO .refailCause(cause.stripFailures && causes)
2548
- case _ => ZIO .refailCause(cause.stripFailures)
2549
- }
2550
- },
2551
- leftWins =>
2552
- if (leftWins) left.join.zipWith(right.join)((a, b) => f(a, b))
2553
- else right.join.zipWith(left.join)((b, a) => f(a, b))
2554
- )
2541
+ ZIO .parallelFinalizersMask(restore => fork(restore(self), false ).zip(fork(restore(that), true ))).flatMap {
2542
+ case (left, right) =>
2543
+ restore(promise.await).foldCauseZIO(
2544
+ cause =>
2545
+ left.interruptFork *> right.interruptFork *>
2546
+ left.await.zip(right.await).flatMap { case (left, right) =>
2547
+ left.zipWith(right)(f, _ && _) match {
2548
+ case Exit .Failure (causes) => ZIO .refailCause(cause.stripFailures && causes)
2549
+ case _ => ZIO .refailCause(cause.stripFailures)
2550
+ }
2551
+ },
2552
+ leftWins =>
2553
+ if (leftWins) left.join.zipWith(right.join)((a, b) => f(a, b))
2554
+ else right.join.zipWith(left.join)((b, a) => f(a, b))
2555
+ )
2555
2556
}
2556
2557
}
2557
2558
}
@@ -4254,8 +4255,30 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific
4254
4255
* Returns a new scoped workflow that runs finalizers added to the scope of
4255
4256
* this workflow in parallel.
4256
4257
*/
4257
- def parallelFinalizers [R , E , A ](zio : => ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R with Scope , E , A ] =
4258
- ZIO .scopeWith(_.forkWith(ExecutionStrategy .Parallel ).flatMap(_.extend[R ](zio)))
4258
+ def parallelFinalizers [R , E , A ](zio : => ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
4259
+ ZIO .environmentWithZIO[R ] { environment =>
4260
+ environment.getDynamic[Scope ] match {
4261
+ case None => zio
4262
+ case Some (scope) =>
4263
+ scope.executionStrategy match {
4264
+ case ExecutionStrategy .Parallel => zio
4265
+ case _ => scope.forkWith(ExecutionStrategy .Parallel ).flatMap(_.extend[R ](zio))
4266
+ }
4267
+ }
4268
+ }
4269
+
4270
+ def parallelFinalizersMask [R , E , A ](f : ZIO .FinalizersRestorer => ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
4271
+ ZIO .environmentWithZIO[R ] { environment =>
4272
+ environment.getDynamic[Scope ] match {
4273
+ case None => f(ZIO .FinalizersRestorer .Identity )
4274
+ case Some (scope) =>
4275
+ scope.executionStrategy match {
4276
+ case ExecutionStrategy .Parallel => ZIO .parallelFinalizers(f(ZIO .FinalizersRestorer .MakeParallel ))
4277
+ case ExecutionStrategy .ParallelN (n) => ZIO .parallelFinalizers(f(ZIO .FinalizersRestorer .MakeParallelN (n)))
4278
+ case ExecutionStrategy .Sequential => ZIO .parallelFinalizers(f(ZIO .FinalizersRestorer .MakeSequential ))
4279
+ }
4280
+ }
4281
+ }
4259
4282
4260
4283
/**
4261
4284
* Retrieves the maximum number of fibers for parallel operators or `None` if
@@ -4459,8 +4482,17 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific
4459
4482
* has meaning if used within a scope where finalizers are being run in
4460
4483
* parallel.
4461
4484
*/
4462
- def sequentialFinalizers [R , E , A ](zio : => ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R with Scope , E , A ] =
4463
- ZIO .scopeWith(_.fork.flatMap(_.extend[R ](zio)))
4485
+ def sequentialFinalizers [R , E , A ](zio : => ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
4486
+ ZIO .environmentWithZIO[R ] { environment =>
4487
+ environment.getDynamic[Scope ] match {
4488
+ case None => zio
4489
+ case Some (scope) =>
4490
+ scope.executionStrategy match {
4491
+ case ExecutionStrategy .Sequential => zio
4492
+ case _ => scope.forkWith(ExecutionStrategy .Sequential ).flatMap(_.extend[R ](zio))
4493
+ }
4494
+ }
4495
+ }
4464
4496
4465
4497
/**
4466
4498
* Sets the `FiberRef` values for the fiber running this effect to the values
@@ -5898,6 +5930,51 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific
5898
5930
}
5899
5931
}
5900
5932
5933
+ sealed trait FinalizersRestorer {
5934
+ def apply [R , E , A ](zio : ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ]
5935
+ }
5936
+
5937
+ object FinalizersRestorer {
5938
+ def apply (executionStrategy : ExecutionStrategy ): FinalizersRestorer =
5939
+ executionStrategy match {
5940
+ case ExecutionStrategy .Sequential =>
5941
+ FinalizersRestorer .MakeSequential
5942
+ case ExecutionStrategy .Parallel =>
5943
+ FinalizersRestorer .MakeParallel
5944
+ case ExecutionStrategy .ParallelN (n) =>
5945
+ FinalizersRestorer .MakeParallelN (n)
5946
+ }
5947
+
5948
+ case object Identity extends FinalizersRestorer {
5949
+ def apply [R , E , A ](zio : ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
5950
+ zio
5951
+ }
5952
+
5953
+ case object MakeParallel extends FinalizersRestorer {
5954
+ def apply [R , E , A ](zio : ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
5955
+ zio.parallelFinalizers
5956
+ }
5957
+
5958
+ final case class MakeParallelN (n : Int ) extends FinalizersRestorer {
5959
+ def apply [R , E , A ](zio : ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
5960
+ ZIO .environmentWithZIO[R ] { environment =>
5961
+ environment.getDynamic[Scope ] match {
5962
+ case None => zio
5963
+ case Some (scope) =>
5964
+ scope.executionStrategy match {
5965
+ case ExecutionStrategy .ParallelN (n) => zio
5966
+ case _ => scope.forkWith(ExecutionStrategy .ParallelN (n)).flatMap(_.extend[R ](zio))
5967
+ }
5968
+ }
5969
+ }
5970
+ }
5971
+
5972
+ case object MakeSequential extends FinalizersRestorer {
5973
+ def apply [R , E , A ](zio : ZIO [R , E , A ])(implicit trace : Trace ): ZIO [R , E , A ] =
5974
+ zio.sequentialFinalizers
5975
+ }
5976
+ }
5977
+
5901
5978
private [zio] val someFatal = Some (LogLevel .Fatal )
5902
5979
private [zio] val someError = Some (LogLevel .Error )
5903
5980
private [zio] val someWarning = Some (LogLevel .Warning )
@@ -5979,19 +6056,21 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific
5979
6056
val promise = Promise .unsafe.make[Unit , Unit ](FiberId .None )(Unsafe .unsafe)
5980
6057
val ref = new java.util.concurrent.atomic.AtomicInteger (0 )
5981
6058
ZIO .transplant { graft =>
5982
- ZIO .foreach(as) { a =>
5983
- graft {
5984
- restore(ZIO .suspendSucceed(f(a))).foldCauseZIO(
5985
- cause => promise.fail(()) *> ZIO .refailCause(cause),
5986
- _ =>
5987
- if (ref.incrementAndGet == size) {
5988
- promise.unsafe.done(ZIO .unit)(Unsafe .unsafe)
5989
- ZIO .unit
5990
- } else {
5991
- ZIO .unit
5992
- }
5993
- )
5994
- }.forkDaemon
6059
+ ZIO .parallelFinalizersMask { restoreFinalizers =>
6060
+ ZIO .foreach(as) { a =>
6061
+ graft {
6062
+ restore(restoreFinalizers(ZIO .suspendSucceed(f(a)))).foldCauseZIO(
6063
+ cause => promise.fail(()) *> ZIO .refailCause(cause),
6064
+ _ =>
6065
+ if (ref.incrementAndGet == size) {
6066
+ promise.unsafe.done(ZIO .unit)(Unsafe .unsafe)
6067
+ ZIO .unit
6068
+ } else {
6069
+ ZIO .unit
6070
+ }
6071
+ )
6072
+ }.forkDaemon
6073
+ }
5995
6074
}
5996
6075
}.flatMap { fibers =>
5997
6076
restore(promise.await).foldCauseZIO(
0 commit comments