@@ -28,6 +28,142 @@ import Swift
28
28
public struct Task {
29
29
}
30
30
31
+ // ==== Task Priority ----------------------------------------------------------
32
+
33
+ extension Task {
34
+ public struct Priority : Comparable {
35
+ public static let `default` : Task . Priority = . init( ) // TODO: replace with actual values
36
+
37
+ // TODO: specifics of implementation are not decided yet
38
+ let __value : Int = 0
39
+
40
+ public static func < ( lhs: Self , rhs: Self ) -> Bool {
41
+ lhs. __value < rhs. __value
42
+ }
43
+ }
44
+ }
45
+
46
+ // ==== Task Handle ------------------------------------------------------------
47
+
48
+ extension Task {
49
+
50
+ /// A task handle refers to an in-flight `Task`, allowing for (potentially)
51
+ /// awaiting for its result or potentially canceling it.
52
+ public final class Handle < Success, Failure: Error > {
53
+
54
+ /// Wait for the task to complete, returning (or throwing) its result.
55
+ ///
56
+ /// ### Priority
57
+ /// If the task has not completed yet, its priority will be elevated to the
58
+ /// priority of the current task. Note that this may not be as effective as
59
+ /// creating the task with the "right" priority to in the first place.
60
+ public func get( ) async throws -> Success {
61
+ fatalError ( " \( #function) not implemented yet. " )
62
+ }
63
+
64
+ /// Attempt to cancel the task.
65
+ ///
66
+ /// Whether this function has any effect is task-dependent.
67
+ ///
68
+ /// For a task to respect cancellation it must cooperatively check for it
69
+ /// while running. Many tasks will check for cancellation before beginning
70
+ /// their "actual work", however this is not a requirement nor is it guaranteed
71
+ /// how and when tasks check for cancellation in general.
72
+ public func cancel( ) {
73
+ fatalError ( " \( #function) not implemented yet. " )
74
+ }
75
+ }
76
+ }
77
+
78
+ extension Task . Handle where Failure == Never {
79
+ /// Wait for the task to complete, returning its result.
80
+ ///
81
+ /// ### Priority
82
+ /// If the task has not completed yet, its priority will be elevated to the
83
+ /// priority of the current task. Note that this may not be as effective as
84
+ /// creating the task with the "right" priority to in the first place.
85
+ public func get( ) async -> Success {
86
+ fatalError ( " \( #function) not implemented yet. " )
87
+ }
88
+ }
89
+
90
+ // ==== Detached Tasks ---------------------------------------------------------
91
+
92
+ extension Task {
93
+ /// Run given `operation` as part of a new top-level task.
94
+ ///
95
+ /// Creating detached tasks should, generally, be avoided in favor of using
96
+ /// `async` functions, `async let` declarations and `await` expressions - as
97
+ /// those benefit from structured, bounded concurrency which is easier to reason
98
+ /// about, as well as automatically inheriting the parent tasks priority,
99
+ /// task-local storage, deadlines, as well as being cancelled automatically
100
+ /// when their parent task is cancelled. Detached tasks do not get any of those
101
+ /// benefits, and thus should only be used when an operation is impossible to
102
+ /// be modelled with child tasks.
103
+ ///
104
+ /// ### Cancellation
105
+ /// A detached task always runs to completion unless it is explicitly cancelled.
106
+ /// Specifically, dropping a detached tasks `Task.Handle` does _not_ automatically
107
+ /// cancel given task.
108
+ ///
109
+ /// Canceling a task must be performed explicitly via `handle.cancel()`.
110
+ ///
111
+ /// - Parameters:
112
+ /// - priority: priority of the task TODO: reword and define more explicitly once we have priorities well-defined
113
+ /// - operation:
114
+ /// - Returns: handle to the task, allowing to `await handle.get()` on the
115
+ /// tasks result or `cancel` it.
116
+ ///
117
+ /// - Note: it is generally preferable to use child tasks rather than detached
118
+ /// tasks. Child tasks automatically carry priorities, task-local state,
119
+ /// deadlines and have other benefits resulting from the structured
120
+ /// concurrency concepts that they model. Consider using detached tasks only
121
+ /// when strictly necessary and impossible to model operations otherwise.
122
+ public static func runDetached< T> (
123
+ priority: Priority = . default,
124
+ operation: ( ) async -> T
125
+ ) -> Handle < T , Never > {
126
+ fatalError ( " \( #function) not implemented yet. " )
127
+ }
128
+
129
+ /// Run given throwing `operation` as part of a new top-level task.
130
+ ///
131
+ /// Creating detached tasks should, generally, be avoided in favor of using
132
+ /// `async` functions, `async let` declarations and `await` expressions - as
133
+ /// those benefit from structured, bounded concurrency which is easier to reason
134
+ /// about, as well as automatically inheriting the parent tasks priority,
135
+ /// task-local storage, deadlines, as well as being cancelled automatically
136
+ /// when their parent task is cancelled. Detached tasks do not get any of those
137
+ /// benefits, and thus should only be used when an operation is impossible to
138
+ /// be modelled with child tasks.
139
+ ///
140
+ /// ### Cancellation
141
+ /// A detached task always runs to completion unless it is explicitly cancelled.
142
+ /// Specifically, dropping a detached tasks `Task.Handle` does _not_ automatically
143
+ /// cancel given task.
144
+ ///
145
+ /// Canceling a task must be performed explicitly via `handle.cancel()`.
146
+ ///
147
+ /// - Parameters:
148
+ /// - priority: priority of the task TODO: reword and define more explicitly once we have priorities well-defined
149
+ /// - operation:
150
+ /// - Returns: handle to the task, allowing to `await handle.get()` on the
151
+ /// tasks result or `cancel` it. If the operation fails the handle will
152
+ /// throw the error the operation has thrown when awaited on.
153
+ ///
154
+ /// - Note: it is generally preferable to use child tasks rather than detached
155
+ /// tasks. Child tasks automatically carry priorities, task-local state,
156
+ /// deadlines and have other benefits resulting from the structured
157
+ /// concurrency concepts that they model. Consider using detached tasks only
158
+ /// when strictly necessary and impossible to model operations otherwise.
159
+ public static func runDetached< T> (
160
+ priority: Priority = . default,
161
+ operation: ( ) async throws -> T
162
+ ) -> Handle < T , Error > {
163
+ fatalError ( " \( #function) not implemented yet. " )
164
+ }
165
+ }
166
+
31
167
// ==== UnsafeContinuation -----------------------------------------------------
32
168
33
169
extension Task {
0 commit comments