-
Notifications
You must be signed in to change notification settings - Fork 26
[Performance]Break async stream memory leaks #826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ipavlidakis
merged 3 commits into
fix/performance-improvements
from
fix/performance-improvements-subtasks/break-async-stream-memory-leaks
May 28, 2025
Merged
[Performance]Break async stream memory leaks #826
ipavlidakis
merged 3 commits into
fix/performance-improvements
from
fix/performance-improvements-subtasks/break-async-stream-memory-leaks
May 28, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Public Interface+ extension ScreenPropertiesAdapter: InjectionKey
+
+ public nonisolated static var currentValue: ScreenPropertiesAdapter
+ public final class ScreenPropertiesAdapter: @unchecked Sendable
+
+ public private var preferredFramesPerSecond: Int
+ public private var refreshRate: TimeInterval
+ public private var scale: CGFloat
+ public protocol TimerProviding
public class StreamVideo: ObservableObject, @unchecked Sendable
- public var state: State
+ case ringEventReceived
- public let videoConfig: VideoConfig
+
- public var user: User
+
- public var isHardwareAccelerationAvailable: Bool
+ public var state: State
- public lazy var rejectionReasonProvider: RejectionReasonProviding
+ public let videoConfig: VideoConfig
-
+ public var user: User
-
+ public var isHardwareAccelerationAvailable: Bool
- public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
+ public lazy var rejectionReasonProvider: RejectionReasonProviding
- public func connect()async throws
+ public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
- public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
+
- public func makeCallsController(callsQuery: CallsQuery)-> CallsController
+
- @discardableResult public func setDevice(id: String)async throws -> ModelResponse
+ public func connect()async throws
- @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
+ public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
- @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
+ public func makeCallsController(callsQuery: CallsQuery)-> CallsController
- public func listDevices()async throws -> [Device]
+ @discardableResult public func setDevice(id: String)async throws -> ModelResponse
- public func disconnect()async
+ @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
- public func subscribe()-> AsyncStream<VideoEvent>
+ @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
- public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
+ public func listDevices()async throws -> [Device]
- public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func disconnect()async
- public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func eventPublisher()-> AnyPublisher<VideoEvent, Never>
-
+ public func eventPublisher(for event: WSEvent.Type)-> AnyPublisher<WSEvent, Never>
-
+ public func subscribe()-> AsyncStream<VideoEvent>
- public final class State: ObservableObject, @unchecked Sendable
+ public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
-
+ public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var connection: ConnectionStatus
+ public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var user: User
+
- @Published public internal var activeCall: Call?
+
- @Published public internal var ringingCall: Call?
+ public final class State: ObservableObject, @unchecked Sendable
+
+ @Published public internal var connection: ConnectionStatus
+ @Published public internal var user: User
+ @Published public internal var activeCall: Call?
+ @Published public internal var ringingCall: Call? |
SDK Size
|
Public Interface+ extension ScreenPropertiesAdapter: InjectionKey
+
+ public nonisolated static var currentValue: ScreenPropertiesAdapter
+ public final class ScreenPropertiesAdapter: @unchecked Sendable
+
+ public private var preferredFramesPerSecond: Int
+ public private var refreshRate: TimeInterval
+ public private var scale: CGFloat
+ public protocol TimerProviding
public class StreamVideo: ObservableObject, @unchecked Sendable
- public var state: State
+ case ringEventReceived
- public let videoConfig: VideoConfig
+
- public var user: User
+
- public var isHardwareAccelerationAvailable: Bool
+ public var state: State
- public lazy var rejectionReasonProvider: RejectionReasonProviding
+ public let videoConfig: VideoConfig
-
+ public var user: User
-
+ public var isHardwareAccelerationAvailable: Bool
- public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
+ public lazy var rejectionReasonProvider: RejectionReasonProviding
- public func connect()async throws
+ public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
- public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
+
- public func makeCallsController(callsQuery: CallsQuery)-> CallsController
+
- @discardableResult public func setDevice(id: String)async throws -> ModelResponse
+ public func connect()async throws
- @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
+ public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
- @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
+ public func makeCallsController(callsQuery: CallsQuery)-> CallsController
- public func listDevices()async throws -> [Device]
+ @discardableResult public func setDevice(id: String)async throws -> ModelResponse
- public func disconnect()async
+ @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
- public func subscribe()-> AsyncStream<VideoEvent>
+ @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
- public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
+ public func listDevices()async throws -> [Device]
- public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func disconnect()async
- public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func eventPublisher()-> AnyPublisher<VideoEvent, Never>
-
+ public func eventPublisher(for event: WSEvent.Type)-> AnyPublisher<WSEvent, Never>
-
+ public func subscribe()-> AsyncStream<VideoEvent>
- public final class State: ObservableObject, @unchecked Sendable
+ public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
-
+ public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var connection: ConnectionStatus
+ public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var user: User
+
- @Published public internal var activeCall: Call?
+
- @Published public internal var ringingCall: Call?
+ public final class State: ObservableObject, @unchecked Sendable
+
+ @Published public internal var connection: ConnectionStatus
+ @Published public internal var user: User
+ @Published public internal var activeCall: Call?
+ @Published public internal var ringingCall: Call? |
Public Interface+ extension ScreenPropertiesAdapter: InjectionKey
+
+ public nonisolated static var currentValue: ScreenPropertiesAdapter
+ public final class ScreenPropertiesAdapter: @unchecked Sendable
+
+ public private var preferredFramesPerSecond: Int
+ public private var refreshRate: TimeInterval
+ public private var scale: CGFloat
+ public protocol TimerProviding
public class StreamVideo: ObservableObject, @unchecked Sendable
- public var state: State
+ case ringEventReceived
- public let videoConfig: VideoConfig
+
- public var user: User
+
- public var isHardwareAccelerationAvailable: Bool
+ public var state: State
- public lazy var rejectionReasonProvider: RejectionReasonProviding
+ public let videoConfig: VideoConfig
-
+ public var user: User
-
+ public var isHardwareAccelerationAvailable: Bool
- public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
+ public lazy var rejectionReasonProvider: RejectionReasonProviding
- public func connect()async throws
+ public convenience init(apiKey: String,user: User,token: UserToken,videoConfig: VideoConfig = VideoConfig(),pushNotificationsConfig: PushNotificationsConfig = .default,tokenProvider: UserTokenProvider? = nil)
- public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
+
- public func makeCallsController(callsQuery: CallsQuery)-> CallsController
+
- @discardableResult public func setDevice(id: String)async throws -> ModelResponse
+ public func connect()async throws
- @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
+ public func call(callType: String,callId: String,callSettings: CallSettings? = nil)-> Call
- @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
+ public func makeCallsController(callsQuery: CallsQuery)-> CallsController
- public func listDevices()async throws -> [Device]
+ @discardableResult public func setDevice(id: String)async throws -> ModelResponse
- public func disconnect()async
+ @discardableResult public func setVoipDevice(id: String)async throws -> ModelResponse
- public func subscribe()-> AsyncStream<VideoEvent>
+ @discardableResult public func deleteDevice(id: String)async throws -> ModelResponse
- public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
+ public func listDevices()async throws -> [Device]
- public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func disconnect()async
- public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
+ public func eventPublisher()-> AnyPublisher<VideoEvent, Never>
-
+ public func eventPublisher(for event: WSEvent.Type)-> AnyPublisher<WSEvent, Never>
-
+ public func subscribe()-> AsyncStream<VideoEvent>
- public final class State: ObservableObject, @unchecked Sendable
+ public func subscribe(for event: WSEvent.Type)-> AsyncStream<WSEvent>
-
+ public func queryCalls(next: String? = nil,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var connection: ConnectionStatus
+ public func queryCalls(filters: [String: RawJSON]?,sort: [SortParamRequest] = [SortParamRequest.descending("created_at")],limit: Int? = 25,watch: Bool = false)async throws -> (calls: [Call], next: String?)
- @Published public internal var user: User
+
- @Published public internal var activeCall: Call?
+
- @Published public internal var ringingCall: Call?
+ public final class State: ObservableObject, @unchecked Sendable
+
+ @Published public internal var connection: ConnectionStatus
+ @Published public internal var user: User
+ @Published public internal var activeCall: Call?
+ @Published public internal var ringingCall: Call? |
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🎯 Goal
AsyncStreams are causing leaks on continuations. This revision attempts to fix that by backing AsyncStream on StreamVideo, by Combine Publishers
🧪 Manual Testing Notes
✅ Call Test Summary
Scenario
1:1 call
for 5 minutesnoise-cancellation: active
background-filter: inactive
profiler: connected
debugger: disconnected
🧵 Tasks
🌡️ Thermal State Degradation
☑️ Contributor Checklist