Skip to content

Commit 518f767

Browse files
committed
Make Async.Group a field in Async instead of inheriting from it
1 parent 7819b61 commit 518f767

File tree

3 files changed

+27
-26
lines changed

3 files changed

+27
-26
lines changed

tests/run/suspend-strawman-2/Async.scala

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,40 @@ import scala.collection.mutable
44

55
/** A context that allows to suspend waiting for asynchronous data sources
66
*/
7-
trait Async extends Async.Config:
7+
trait Async:
88

99
/** Wait for completion of async source `src` and return the result */
1010
def await[T](src: Async.Source[T]): T
1111

12-
/** An Async of the same kind as this one, with a given cancellation group */
13-
def withGroup(group: Cancellable.Group): Async
12+
/** The configuration of this Async */
13+
def config: Async.Config
14+
15+
/** An Async of the same kind as this one, with a new configuration as given */
16+
def withConfig(config: Async.Config): Async
1417

1518
object Async:
1619

1720
/** The underlying configuration of an async block */
18-
trait Config:
19-
20-
/** The group of cancellableup to which nested futures belong */
21-
def group: Cancellable.Group
21+
case class Config(scheduler: Scheduler, group: Cancellable.Group)
2222

23-
/** The scheduler for runnables defined in this async computation */
24-
def scheduler: Scheduler
25-
26-
object Config:
23+
trait LowPrioConfig:
2724

2825
/** A toplevel async group with given scheduler and a synthetic root that
2926
* ignores cancellation requests
3027
*/
31-
given fromScheduler(using s: Scheduler): Config with
32-
def group = Cancellable.Unlinked
33-
def scheduler = s
28+
given fromScheduler(using s: Scheduler): Config = Config(s, Cancellable.Unlinked)
29+
30+
end LowPrioConfig
31+
32+
object Config extends LowPrioConfig:
33+
34+
/** The async configuration stored in the given async capabaility */
35+
given fromAsync(using async: Async): Config = async.config
3436

3537
end Config
3638

3739
/** An implementation of Async that blocks the running thread when waiting */
38-
private class Blocking(val scheduler: Scheduler, val group: Cancellable.Group) extends Async:
40+
private class Blocking(using val config: Config) extends Async:
3941

4042
def await[T](src: Source[T]): T =
4143
src.poll().getOrElse:
@@ -49,15 +51,14 @@ object Async:
4951
while result.isEmpty do wait()
5052
result.get
5153

52-
def withGroup(group: Cancellable.Group) = Blocking(scheduler, group)
54+
def withConfig(config: Config) = Blocking(using config)
5355
end Blocking
5456

55-
5657
/** Execute asynchronous computation `body` on currently running thread.
5758
* The thread will suspend when the computation waits.
5859
*/
59-
def blocking[T](body: Async ?=> T, scheduler: Scheduler = Scheduler): T =
60-
body(using Blocking(scheduler, Cancellable.Unlinked))
60+
def blocking[T](body: Async ?=> T)(using Scheduler): T =
61+
body(using Blocking())
6162

6263
/** The currently executing Async context */
6364
inline def current(using async: Async): Async = async
@@ -67,7 +68,7 @@ object Async:
6768

6869
def group[T](body: Async ?=> T)(using async: Async): T =
6970
val newGroup = Cancellable.Group().link()
70-
body(using async.withGroup(newGroup))
71+
body(using async.withConfig(async.config.copy(group = newGroup)))
7172

7273
/** A function `T => Boolean` whose lineage is recorded by its implementing
7374
* classes. The Listener function accepts values of type `T` and returns

tests/run/suspend-strawman-2/Cancellable.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ trait Cancellable:
2121
/** Link this cancellable to the cancellable group of the
2222
* current async context.
2323
*/
24-
def link()(using ac: Async): this.type =
25-
link(ac.group)
24+
def link()(using async: Async): this.type =
25+
link(async.config.group)
2626

2727
/** Unlink this cancellable from its group. */
2828
def unlink(): this.type =

tests/run/suspend-strawman-2/futures.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ object Future:
8888

8989
/** a handler for Async */
9090
private def async(body: Async ?=> Unit): Unit =
91-
class FutureAsync(val scheduler: Scheduler, val group: Cancellable.Group) extends Async:
91+
class FutureAsync(using val config: Async.Config) extends Async:
9292

9393
def checkCancellation() =
9494
if cancelRequest then throw CancellationException()
@@ -103,7 +103,7 @@ object Future:
103103
var result: Option[T] = None // Not needed if we have full continuations
104104
suspend[T, Unit]: k =>
105105
src.onComplete: x =>
106-
scheduler.schedule: () =>
106+
config.scheduler.schedule: () =>
107107
result = Some(x)
108108
k.resume()
109109
true // signals to `src` that result `x` was consumed
@@ -118,10 +118,10 @@ object Future:
118118
*/
119119
finally checkCancellation()
120120

121-
def withGroup(group: Cancellable.Group) = FutureAsync(scheduler, group)
121+
def withConfig(config: Async.Config) = FutureAsync(using config)
122122

123123
boundary [Unit]:
124-
body(using FutureAsync(ac.scheduler, ac.group))
124+
body(using FutureAsync())
125125
end async
126126

127127
ac.scheduler.schedule: () =>

0 commit comments

Comments
 (0)