Skip to content

[Enhancement]Improve swift concurrency task lifecycle - #861

Merged
ipavlidakis merged 16 commits into
developfrom
enhancement/improve-swift-concurrency-task-lifecycle
Jun 23, 2025
Merged

ipavlidakis merged 16 commits into
developfrom
enhancement/improve-swift-concurrency-task-lifecycle

Conversation

@ipavlidakis

Copy link
Copy Markdown
Contributor

🎯 Goal

Improve Swift Concurrency Task lifecycle by 1. providing a simple way to manage a Task's lifecycle, 2. avoid keeping Tasks in memory to reduce memory usage.

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change follows zero ⚠️ policy (required)
  • This change should receive manual QA
  • Changelog is updated with client-facing changes
  • New code is covered by unit tests
  • Comparison screenshots added for visual changes
  • Affected documentation updated (tutorial, CMS)

@ipavlidakis ipavlidakis self-assigned this Jun 20, 2025
@ipavlidakis
ipavlidakis requested a review from a team as a code owner June 20, 2025 15:51
@ipavlidakis ipavlidakis added the bug Something isn't working label Jun 20, 2025
@Stream-SDK-Bot

Stream-SDK-Bot commented Jun 20, 2025

Copy link
Copy Markdown
Collaborator

SDK Size

title develop branch diff status
StreamVideo 7.93 MB 8.06 MB +137 KB 🟢
StreamVideoSwiftUI 2.25 MB 2.27 MB +18 KB 🟢
StreamVideoUIKit 2.38 MB 2.39 MB +17 KB 🟢
StreamWebRTC 9.85 MB 9.85 MB 0 KB 🟢

@github-actions

Copy link
Copy Markdown

Public Interface

+ public protocol Signposting

+ public actor SerialActorQueue  
+ 
+   nonisolated public var unownedExecutor: UnownedSerialExecutor
+   
+ 
+   public init(file: StaticString = #file)
+   
+ 
+   @discardableResult public nonisolated func async(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext operation: @escaping Operation)-> QueueTask
+   @discardableResult public nonisolated func async(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext operation: @escaping @Sendable() async -> Void)-> QueueTask
+   @discardableResult public nonisolated func sync(@_inheritActorContext operation: @escaping @Sendable() async throws -> Output)async throws -> Output
+   @discardableResult public nonisolated func async(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)-> QueueTask
+   @discardableResult public nonisolated func sync(@_inheritActorContext operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output
+   public nonisolated func cancelAll()
+   
+ 
+   public final class QueueTask: @unchecked Sendable

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(queue: SerialActorQueue,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

@github-actions

github-actions Bot commented Jun 20, 2025

Copy link
Copy Markdown
1 Error
🚫 Please use more than one word.
0b7da11
1 Warning
⚠️ Big PR

Generated by 🚫 Danger

@github-actions

Copy link
Copy Markdown

Public Interface

+ extension OperationQueue  
+ 
+   public func addTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)
+   public func addSynchronousTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,timeout: TimeInterval = 10,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output

+ public protocol Signposting

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

@github-actions

Copy link
Copy Markdown

Public Interface

+ extension OperationQueue  
+ 
+   public func addTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)
+   public func addSynchronousTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,timeout: TimeInterval = 10,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output

+ public protocol Signposting

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

@github-actions

Copy link
Copy Markdown

Public Interface

+ public protocol Signposting

+ extension OperationQueue  
+ 
+   public func addTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)
+   public func addSynchronousTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,timeout: TimeInterval = 10,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

@martinmitrevski martinmitrevski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impressive work 👏 Added a few small comments and we should check the failed checks before merging.

Comment thread Sources/StreamVideo/CallSettings/CallSettingsManager.swift
Comment thread Sources/StreamVideo/Utils/CurrentDevice/CurrentDevice.swift Outdated
Comment thread Sources/StreamVideo/Utils/DeviceOrientation/StreamDeviceOrientationAdapter.swift Outdated
Comment thread Sources/StreamVideo/Utils/Logger/Signposting.swift Outdated

/// Deinitializes the instance, deallocating the unfair lock.
deinit {
lock.deinitialize(count: 1)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why 1?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the allocated capacity was 1, so we are only deinitializing what we allocated intially.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the problem is what if we change something in the future - we always have to remember to update this as well?

Comment thread Sources/StreamVideo/Utils/SerialActorQueue/OperationQueue+TaskOperations.swift Outdated
Comment thread Sources/StreamVideo/WebRTC/v2/PeerConnection/Adapters/ICEAdapter.swift Outdated
/// Cleans up resources when the instance is being deallocated.
deinit {
peerConnection.transceivers.forEach { $0.stopInternal() }
// swiftlint:disable discourage_task_init

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we're too strict with this rule?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually intended. The plan is to avoid having Tasks that there is no way to control their lifecycle (e.g. cancel them). Do you think we should relax it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so - we should have this only in the core parts. What do you think?

Comment thread Sources/StreamVideo/WebSockets/Events/EventNotificationCenter.swift Outdated
Comment thread Sources/StreamVideoSwiftUI/CallViewModel.swift Outdated
@ipavlidakis
ipavlidakis force-pushed the enhancement/improve-swift-concurrency-task-lifecycle branch from 2cd6cc1 to 6a6c124 Compare June 23, 2025 13:56
@github-actions

Copy link
Copy Markdown

Public Interface

+ extension OperationQueue  
+ 
+   public func addTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)
+   public func addSynchronousTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,timeout: TimeInterval = 5,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output

+ public protocol Signposting

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

@github-actions

Copy link
Copy Markdown

Public Interface

+ public protocol Signposting

+ extension OperationQueue  
+ 
+   public func addTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Void)
+   public func addSynchronousTaskOperation(file: StaticString = #file,function: StaticString = #function,line: UInt = #line,timeout: TimeInterval = 5,operation: sending @escaping @Sendable @isolated(any) () async throws (Failure) -> Output)async throws -> Output

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

@github-actions

Copy link
Copy Markdown

Public Interface

+ public protocol Signposting

- public final class SerialActorQueue: Sendable  
- 
-   public init()
-   
- 
-   public func cancelAll()
-   public func async(file: StaticString = #file,functionName: StaticString = #function,line: UInt = #line,_ block: @Sendable @escaping () async throws -> Void)
-   public func sync(_ block: @Sendable @escaping () async throws -> T)async throws -> T

 public final class CurrentDevice: @unchecked Sendable  
+     case simulator

 public final class DisposableBag: @unchecked Sendable  
+   public func completed(_ key: String)

 extension Publisher  
-   public func sinkTask(storeIn disposableBag: DisposableBag? = nil,identifier: String? = nil,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
+   public func sinkTask(storeIn disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable
-   public func sinkTask(queue: SerialActorQueue,receiveCompletion: @escaping (@Sendable(Subscribers.Completion<Failure>) -> Void) = { _ in },receiveValue: @escaping (@Sendable(Output) async throws -> Void))-> AnyCancellable

- public enum CallingState: Equatable, CustomStringConvertible  
+ public enum CallingState: Equatable, CustomStringConvertible, Sendable  

 extension Task  
-   public func store(in disposableBag: DisposableBag,key: String = UUID().uuidString)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async -> Success)
+   @discardableResult public init(disposableBag: DisposableBag,identifier: String = UUIDProviderKey.currentValue.get().uuidString,priority: TaskPriority? = nil,subsystem: LogSubsystem = .other,file: StaticString = #file,function: StaticString = #function,line: UInt = #line,@_inheritActorContext block: @Sendable @escaping () async throws -> Success)
+   
+ 
+   public func store(in disposableBag: DisposableBag,identifier: String = UUID().uuidString)

@sonarqubecloud

Copy link
Copy Markdown

@ipavlidakis
ipavlidakis merged commit c9b6db3 into develop Jun 23, 2025
@ipavlidakis
ipavlidakis deleted the enhancement/improve-swift-concurrency-task-lifecycle branch June 23, 2025 17:34
@ipavlidakis ipavlidakis mentioned this pull request Jun 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants