Skip to content

Commit 2c65e12

Browse files
committed
Polling confirmations: Remove the isolation paramater
Have the polling bodies themselves specify nonisolated(nonsending). Keep the escaping attribute for polling bodies. While not strictly necessary, I strongly suspect that a future refactor to use task execution time will make that requirement necessary.
1 parent 7d2b657 commit 2c65e12

File tree

3 files changed

+15
-25
lines changed

3 files changed

+15
-25
lines changed

Sources/Testing/Confirmations/Polling.swift

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ extension PollingFailedError: CustomIssueRepresentable {
109109
/// If no such trait has been added, then polling will wait at least
110110
/// 1 millisecond between polling attempts.
111111
/// `interval` must be greater than 0.
112-
/// - isolation: The actor to which `body` is isolated, if any.
113112
/// - sourceLocation: The location in source where the confirmation was called.
114113
/// - body: The function to invoke. The expression is considered to pass if
115114
/// the `body` returns true. Similarly, the expression is considered to fail
@@ -129,9 +128,8 @@ public func confirmation(
129128
until stopCondition: PollingStopCondition,
130129
within duration: Duration? = nil,
131130
pollingEvery interval: Duration? = nil,
132-
isolation: isolated (any Actor)? = #isolation,
133131
sourceLocation: SourceLocation = #_sourceLocation,
134-
_ body: @escaping () async throws -> Bool
132+
_ body: nonisolated(nonsending) @escaping () async throws -> Bool
135133
) async throws {
136134
let poller = Poller(
137135
stopCondition: stopCondition,
@@ -143,7 +141,7 @@ public func confirmation(
143141
sourceLocation: sourceLocation
144142
)
145143
)
146-
try await poller.evaluate(isolation: isolation) {
144+
try await poller.evaluate() {
147145
do {
148146
return try await body()
149147
} catch {
@@ -174,7 +172,6 @@ public func confirmation(
174172
/// If no such trait has been added, then polling will wait at least
175173
/// 1 millisecond between polling attempts.
176174
/// `interval` must be greater than 0.
177-
/// - isolation: The actor to which `body` is isolated, if any.
178175
/// - sourceLocation: The location in source where the confirmation was called.
179176
/// - body: The function to invoke. The expression is considered to pass if
180177
/// the `body` returns a non-nil value. Similarly, the expression is
@@ -197,9 +194,8 @@ public func confirmation<R>(
197194
until stopCondition: PollingStopCondition,
198195
within duration: Duration? = nil,
199196
pollingEvery interval: Duration? = nil,
200-
isolation: isolated (any Actor)? = #isolation,
201197
sourceLocation: SourceLocation = #_sourceLocation,
202-
_ body: @escaping () async throws -> sending R?
198+
_ body: nonisolated(nonsending) @escaping () async throws -> sending R?
203199
) async throws -> R {
204200
let poller = Poller(
205201
stopCondition: stopCondition,
@@ -211,7 +207,7 @@ public func confirmation<R>(
211207
sourceLocation: sourceLocation
212208
)
213209
)
214-
return try await poller.evaluateOptional(isolation: isolation) {
210+
return try await poller.evaluateOptional() {
215211
do {
216212
return try await body()
217213
} catch {
@@ -242,7 +238,7 @@ private func getValueFromTrait<TraitKind, Value>(
242238
providedValue: Value?,
243239
default: Value,
244240
_ keyPath: KeyPath<TraitKind, Value?>,
245-
where filter: @escaping (TraitKind) -> Bool
241+
where filter: (TraitKind) -> Bool
246242
) -> Value {
247243
if let providedValue { return providedValue }
248244
guard let test = Test.current else { return `default` }
@@ -348,7 +344,6 @@ private struct Poller {
348344
/// Evaluate polling, throwing an error if polling fails.
349345
///
350346
/// - Parameters:
351-
/// - isolation: The actor isolation to use.
352347
/// - body: The expression to poll.
353348
///
354349
/// - Throws: A ``PollingFailedError`` if polling doesn't pass.
@@ -358,10 +353,9 @@ private struct Poller {
358353
/// - Side effects: If polling fails (see ``PollingStopCondition``), then
359354
/// this will record an issue.
360355
@discardableResult func evaluate(
361-
isolation: isolated (any Actor)?,
362-
_ body: @escaping () async -> Bool
356+
_ body: nonisolated(nonsending) @escaping () async -> Bool
363357
) async throws -> Bool {
364-
try await evaluateOptional(isolation: isolation) {
358+
try await evaluateOptional() {
365359
if await body() {
366360
// return any non-nil value.
367361
return true
@@ -374,7 +368,6 @@ private struct Poller {
374368
/// Evaluate polling, throwing an error if polling fails.
375369
///
376370
/// - Parameters:
377-
/// - isolation: The actor isolation to use.
378371
/// - body: The expression to poll.
379372
///
380373
/// - Throws: A ``PollingFailedError`` if polling doesn't pass.
@@ -384,8 +377,7 @@ private struct Poller {
384377
/// - Side effects: If polling fails (see ``PollingStopCondition``), then
385378
/// this will record an issue.
386379
@discardableResult func evaluateOptional<R>(
387-
isolation: isolated (any Actor)?,
388-
_ body: @escaping () async -> sending R?
380+
_ body: nonisolated(nonsending) @escaping () async -> sending R?
389381
) async throws -> R {
390382
precondition(interval > Duration.zero)
391383
precondition(duration >= interval)
@@ -399,7 +391,6 @@ private struct Poller {
399391
let failureReason: PollingFailedError.Reason
400392
switch await poll(
401393
iterations: iterations,
402-
isolation: isolation,
403394
expression: body
404395
) {
405396
case let .succeeded(value):
@@ -431,14 +422,12 @@ private struct Poller {
431422
///
432423
/// - Parameters:
433424
/// - iterations: The maximum amount of times to continue polling.
434-
/// - isolation: The actor isolation to use.
435425
/// - expression: An expression to continuously evaluate.
436426
///
437427
/// - Returns: The most recent value if the polling succeeded, else nil.
438428
private func poll<R>(
439429
iterations: Int,
440-
isolation: isolated (any Actor)?,
441-
expression: @escaping () async -> sending R?
430+
expression: nonisolated(nonsending) @escaping () async -> sending R?
442431
) async -> PollingResult<R> {
443432
for iteration in 0..<iterations {
444433
switch stopCondition.process(

Sources/Testing/Issues/Issue.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ public struct Issue: Sendable {
4444
/// - reason: The ``PollingFailedError.Reason`` behind why the polling
4545
/// confirmation failed.
4646
///
47-
/// This issue can occur when calling ``confirmation(_:until:within:pollingEvery:isolation:sourceLocation:_:)-455gr``
48-
/// or
49-
/// ``confirmation(_:until:within:pollingEvery:isolation:sourceLocation:_:)-5tnlk``
47+
/// This issue can occur when calling
48+
/// ``confirmation(_:until:within:pollingEvery:sourceLocation:_:)->_``
49+
/// and
50+
/// ``confirmation(_:until:within:pollingEvery:sourceLocation:_:)->()``
5051
/// whenever the polling fails, as described in ``PollingStopCondition``.
5152
@_spi(Experimental)
5253
case pollingConfirmationFailed(reason: PollingFailedError.Reason)

Sources/Testing/Traits/PollingConfigurationTrait.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
//
1010

1111
/// A trait to provide a default polling configuration to all usages of
12-
/// ``confirmation(_:until:within:pollingEvery:isolation:sourceLocation:_:)-455gr``
12+
/// ``confirmation(_:until:within:pollingEvery:sourceLocation:_:)->_``
1313
/// and
14-
/// ``confirmation(_:until:within:pollingEvery:isolation:sourceLocation:_:)-5tnlk``
14+
/// ``confirmation(_:until:within:pollingEvery:sourceLocation:_:)->()``
1515
/// within a test or suite using the specified stop condition.
1616
///
1717
/// To add this trait to a test, use the ``Trait/pollingConfirmationDefaults``

0 commit comments

Comments
 (0)