@@ -129,8 +129,8 @@ extension AsyncSharedSequence: AsyncSequence, Sendable {
129
129
guard let state else { return nil }
130
130
let command = state. run ( id)
131
131
switch command {
132
- case . fetch( var iterator) :
133
- let upstreamResult = await Result . async { try await iterator. next ( ) }
132
+ case . fetch( let iterator) :
133
+ let upstreamResult = await iterator. next ( )
134
134
let output = state. fetch ( id, resumedWithResult: upstreamResult, iterator: iterator)
135
135
return try processOutput ( output)
136
136
case . wait:
@@ -194,9 +194,9 @@ fileprivate extension AsyncSharedSequence {
194
194
deinit { action ( ) }
195
195
}
196
196
197
- struct SharedUpstreamIterator : Sendable {
197
+ actor SharedUpstreamIterator {
198
198
199
- private enum State : @ unchecked Sendable {
199
+ private enum State {
200
200
case pending
201
201
case active( Base . AsyncIterator )
202
202
case terminal
@@ -207,36 +207,37 @@ fileprivate extension AsyncSharedSequence {
207
207
return true
208
208
}
209
209
210
- private let createIterator : @ Sendable ( ) -> Base . AsyncIterator
210
+ private let base : Base
211
211
private var state = State . pending
212
212
213
- init ( _ createIterator : @escaping @ Sendable ( ) -> Base . AsyncIterator ) {
214
- self . createIterator = createIterator
213
+ init ( _ base : Base ) {
214
+ self . base = base
215
215
}
216
216
217
- mutating func next( ) async rethrows -> Element ? {
217
+ func next( ) async -> Result < Element ? , Error > {
218
218
switch state {
219
219
case . pending:
220
- self . state = . active( createIterator ( ) )
221
- return try await next ( )
220
+ self . state = . active( base . makeAsyncIterator ( ) )
221
+ return await next ( )
222
222
case . active( var iterator) :
223
- let result = await Result . async { try await iterator. next ( ) }
224
- switch result {
225
- case . success( _? ) :
226
- self . state = . active( iterator)
227
- default :
223
+ do {
224
+ if let element = try await iterator. next ( ) {
225
+ self . state = . active( iterator)
226
+ return . success( element)
227
+ }
228
+ else {
229
+ self . state = . terminal
230
+ return . success( nil )
231
+ }
232
+ }
233
+ catch {
228
234
self . state = . terminal
235
+ return . failure( error)
229
236
}
230
- return try result. _rethrowGet ( )
231
237
case . terminal:
232
- return nil
238
+ return . success ( nil )
233
239
}
234
240
}
235
-
236
- mutating func reset( ) {
237
- guard case . active( _) = state else { return }
238
- self . state = . pending
239
- }
240
241
}
241
242
242
243
struct Runner {
@@ -294,6 +295,7 @@ fileprivate extension AsyncSharedSequence {
294
295
295
296
private struct Storage : Sendable {
296
297
298
+ let base : Base
297
299
let replayCount : Int
298
300
let iteratorDiscardPolicy : IteratorDisposalPolicy
299
301
var iterator : SharedUpstreamIterator ?
@@ -311,9 +313,10 @@ fileprivate extension AsyncSharedSequence {
311
313
312
314
init ( _ base: Base , replayCount: Int , discardsIterator: IteratorDisposalPolicy ) {
313
315
precondition ( replayCount >= 0 , " history must be greater than or equal to zero " )
316
+ self . base = base
314
317
self . replayCount = replayCount
315
318
self . iteratorDiscardPolicy = discardsIterator
316
- self . iterator = . init { base . makeAsyncIterator ( ) }
319
+ self . iterator = . init( base )
317
320
}
318
321
319
322
mutating func establish( ) -> Connection {
@@ -483,7 +486,7 @@ fileprivate extension AsyncSharedSequence {
483
486
self . currentGroup. flip ( )
484
487
self . phase = . pending
485
488
if runners. isEmpty && iteratorDiscardPolicy == . whenTerminatedOrVacant {
486
- self . iterator? . reset ( )
489
+ self . iterator = SharedUpstreamIterator ( base )
487
490
self . history. removeAll ( )
488
491
}
489
492
}
@@ -564,15 +567,3 @@ fileprivate extension AsyncSharedSequence {
564
567
}
565
568
}
566
569
}
567
-
568
- fileprivate extension Result where Failure == Error {
569
-
570
- static func async ( _ operation: @escaping ( ) async throws -> Success ) async -> Self {
571
- do {
572
- return . success( try await operation ( ) )
573
- }
574
- catch let error {
575
- return . failure( error)
576
- }
577
- }
578
- }
0 commit comments