-
Notifications
You must be signed in to change notification settings - Fork 939
/
ExecuteProgress.scala
114 lines (102 loc) · 4.23 KB
/
ExecuteProgress.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
import sbt.internal.util.RMap
/**
* Processes progress events during task execution.
* All methods are called from the same thread except `started` and `finished`,
* which is called from the executing task's thread.
* All methods should return quickly to avoid task execution overhead.
*/
trait ExecuteProgress[F[_]] {
def initial(): Unit
/**
* Notifies that a `task` has been registered in the system for execution.
* The dependencies of `task` are `allDeps` and the subset of those dependencies that
* have not completed are `pendingDeps`.
*/
def afterRegistered(task: F[_], allDeps: Iterable[F[_]], pendingDeps: Iterable[F[_]]): Unit
/**
* Notifies that all of the dependencies of `task` have completed and `task` is therefore
* ready to run. The task has not been scheduled on a thread yet.
*/
def afterReady(task: F[_]): Unit
/**
* Notifies that the work for `task` is starting after this call returns.
* This is called from the thread the task executes on, unlike most other methods in this callback.
* It is called immediately before the task's work starts with minimal intervening executor overhead.
*/
def beforeWork(task: F[_]): Unit
/**
* Notifies that the work for `task` work has finished. The task may have computed the next task to
* run, in which case `result` contains that next task wrapped in Left. If the task produced a value
* or terminated abnormally, `result` provides that outcome wrapped in Right. The ultimate result of
* a task is provided to the `completed` method.
* This is called from the thread the task executes on, unlike most other methods in this callback.
* It is immediately called after the task's work is complete with minimal intervening executor overhead.
*/
def afterWork[A](task: F[A], result: Either[F[A], Result[A]]): Unit
/**
* Notifies that `task` has completed.
* The task's work is done with a final `result`.
* Any tasks called by `task` have completed.
*/
def afterCompleted[A](task: F[A], result: Result[A]): Unit
/** All tasks have completed with the final `results` provided. */
def afterAllCompleted(results: RMap[F, Result]): Unit
/** Notifies that either all tasks have finished or cancelled. */
def stop(): Unit
}
/** This module is experimental and subject to binary and source incompatible changes at any time. */
object ExecuteProgress {
def empty[F[_]]: ExecuteProgress[F] = new ExecuteProgress[F] {
override def initial(): Unit = ()
override def afterRegistered(
task: F[_],
allDeps: Iterable[F[_]],
pendingDeps: Iterable[F[_]]
): Unit =
()
override def afterReady(task: F[_]): Unit = ()
override def beforeWork(task: F[_]): Unit = ()
override def afterWork[A](task: F[A], result: Either[F[A], Result[A]]): Unit = ()
override def afterCompleted[A](task: F[A], result: Result[A]): Unit = ()
override def afterAllCompleted(results: RMap[F, Result]): Unit = ()
override def stop(): Unit = ()
}
def aggregate[F[_]](reporters: Seq[ExecuteProgress[F]]) = new ExecuteProgress[F] {
override def initial(): Unit = {
reporters foreach { _.initial() }
}
override def afterRegistered(
task: F[_],
allDeps: Iterable[F[_]],
pendingDeps: Iterable[F[_]]
): Unit = {
reporters foreach { _.afterRegistered(task, allDeps, pendingDeps) }
}
override def afterReady(task: F[_]): Unit = {
reporters foreach { _.afterReady(task) }
}
override def beforeWork(task: F[_]): Unit = {
reporters foreach { _.beforeWork(task) }
}
override def afterWork[A](task: F[A], result: Either[F[A], Result[A]]): Unit = {
reporters foreach { _.afterWork(task, result) }
}
override def afterCompleted[A](task: F[A], result: Result[A]): Unit = {
reporters foreach { _.afterCompleted(task, result) }
}
override def afterAllCompleted(results: RMap[F, Result]): Unit = {
reporters foreach { _.afterAllCompleted(results) }
}
override def stop(): Unit = {
reporters foreach { _.stop() }
}
}
}