You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The new addition ConcurrentEventStream utilizes the .mapStream to transform elements of an AsyncThrowingStream. However, the method .mapStream produces 3 issues in 3 different scenarios.
Transformed stream never ended
After transforming the base stream using .mapStream, the transformed stream never ended even if the base stream has ended.
// Base stream emits values and end
letbase=AsyncThrowingStream(Int.self){ con inlettask=Task{foriin1...5{
con.yield(i)}
con.finish()}
con.onTermination ={ _ in
task.cancel()}}
// Transform using the `.mapStream`
lettransform= base0.mapStream{"Received from 0: \($0)"}lettask=Task{fortryawait_in transform {}print("Done!!")}
When: base ended with continuation.finish()
Expected: transform ended and "Done!!" is printed
Output: "Done!!" is not printed and transform never ended
Leaks
After transforming the base stream using .mapStream, the base stream is not closed/cancelled/disposed of when the transformed stream is cancelled. Therefore, the base stream will keep emitting values even after the transformed one is no longer consumed.
// Base stream should emit value every second
letbase0=AsyncThrowingStream(Int.self){ con inlettask=Task{foriin1...5{print("Sending for 0: \(i)")
con.yield(i)tryawaitTask.sleep(nanoseconds:1000_000_000)}
con.finish()}
con.onTermination ={ _ in
task.cancel()}}
// Transform using the `.mapStream`
lettransform0= base0.mapStream{"Received from 0: \($0)"}lettask0=Task{fortryawaitmsgin transform0 {print(msg)}}
// Cancel the transformed stream after 1 second (before the base stream ended)
Thread.sleep(forTimeInterval:1)
task0.cancel()
When: transform0 is cancelled but base0 still can emit more values
Expected: base0 is cancelled and stops emitting any more values (preventing leaks)
Output: base0 keeps emitting values
Error lost in transformation
After transforming the base stream using .mapStream and if the base stream finish with an error, that error is not sent to the transformed stream and is lost in the process.
structCustomError:Error{}
// Base stream will throw an error when finished
letbase1=AsyncThrowingStream(Int.self){ con inlettask=Task{foriin1...5{print("Sending for 1: \(i)")
con.yield(i)}print("Sending for 1: CustomError")
con.finish(throwing:CustomError())}
con.onTermination ={ _ in
task.cancel()}}lettransform1= base1.mapStream{"Received from 1: \($0)"}
// Should catch error thrown by base stream
Task{do{fortryawaitmsgin transform1 {print(msg)}return}catch{}print("Done!!")}
When: When base1 ended with an error
Expected:, transform1 should do the same, and an error should be caught ("Done!!" is printed)
Output: transform1 does not end, the error is not caught
Uh oh!
There was an error while loading. Please reload this page.
The new addition
ConcurrentEventStream
utilizes the.mapStream
to transform elements of anAsyncThrowingStream
. However, the method.mapStream
produces 3 issues in 3 different scenarios.Transformed stream never ended
After transforming the base stream using
.mapStream
, the transformed stream never ended even if the base stream has ended.base
ended withcontinuation.finish()
transform
ended and "Done!!" is printedtransform
never endedLeaks
After transforming the base stream using
.mapStream
, the base stream is not closed/cancelled/disposed of when the transformed stream is cancelled. Therefore, the base stream will keep emitting values even after the transformed one is no longer consumed.transform0
is cancelled butbase0
still can emit more valuesbase0
is cancelled and stops emitting any more values (preventing leaks)base0
keeps emitting valuesError lost in transformation
After transforming the base stream using
.mapStream
and if the base stream finish with an error, that error is not sent to the transformed stream and is lost in the process.base1
ended with an errortransform1
should do the same, and an error should be caught ("Done!!" is printed)transform1
does not end, the error is not caughtSolution
#102
The text was updated successfully, but these errors were encountered: