Skip to content

[Enhancement]Simplify Task.timeout and Publisher.nextValue #914

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

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

ipavlidakis
Copy link
Contributor

🎯 Goal

Simplify and improve the Publisher.nextValue and Task.timeout APIs.

🛠 Implementation

Reference for Task.timeout API changes: https://x.com/twannl/status/1950095104254849246

🧪 Manual Testing Notes

  • Join multiple calls and ensure joining works as expected.

☑️ 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 requested a review from Copilot August 19, 2025 11:02
@ipavlidakis ipavlidakis self-assigned this Aug 19, 2025
@ipavlidakis ipavlidakis requested a review from a team as a code owner August 19, 2025 11:02
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR simplifies and improves the Publisher.nextValue and Task.timeout APIs by updating parameter names for better clarity, removing complex cancellation handling, and consolidating functionality into the AsyncStream extension.

  • Renamed Task(timeout:) to Task(timeoutInSeconds:) for clearer parameter naming
  • Removed the Publisher+NextValue.swift file and moved functionality to Publisher+AsyncStream.swift
  • Simplified timer subscription code by removing manual cancellable management

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
StreamVideoTests/WebRTC/v2/WebRTCStateAdapter_Tests.swift Updated Task timeout calls to use new timeoutInSeconds parameter
StreamVideoTests/WebRTC/Extensions/Foundation/Task_TimeoutTests.swift Comprehensive test suite expansion and parameter name updates
StreamVideoTests/Utils/Extensions/Combine/PublisherAsyncStreamTests.swift Added extensive test coverage for Publisher AsyncStream functionality
StreamVideoTests/Mock/MockRTCAudioStore.swift Added proper cleanup in deinit
StreamVideo.xcodeproj/project.pbxproj Removed Publisher+NextValue.swift file reference
Sources/StreamVideo/WebRTC/v2/StateMachine/Stages/WebRTCCoordinator+Disconnected.swift Simplified timer subscription by removing manual cancellable handling
Sources/StreamVideo/WebRTC/v2/Extensions/Foundation/Task+Timeout.swift Refactored timeout implementation with better error handling and parameter naming
Sources/StreamVideo/Utils/StateMachine/Publisher+NextValue.swift File removed - functionality moved
Sources/StreamVideo/Utils/Extensions/Combine/Publisher+AsyncStream.swift Added firstValue and nextValue methods with timeout support
Sources/StreamVideo/StreamVideo.swift Simplified timer subscriptions by removing manual cancellable management

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

///
/// - Note: This implementation uses a task group to manage concurrent execution
/// of the main operation and the timeout timer.
extension Task where Failure == any Error {
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

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

The constraint where Failure == any Error is unnecessarily restrictive. The original constraint where Failure == Error was more appropriate as it allows the extension to work with any concrete Error type, not just existential types.

Suggested change
extension Task where Failure == any Error {
extension Task where Failure == Error {

Copilot uses AI. Check for mistakes.

file: StaticString = #fileID,
function: StaticString = #function,
line: UInt = #line,
operation: @Sendable @escaping @isolated(any) () async throws -> Success
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

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

The @isolated(any) annotation is unnecessary here and may cause compilation issues. The @Sendable @escaping annotations are sufficient for this async operation parameter.

Suggested change
operation: @Sendable @escaping @isolated(any) () async throws -> Success
operation: @Sendable @escaping () async throws -> Success

Copilot uses AI. Check for mistakes.

function: function,
line: line
) {
try await selfReference.firstValue(file: file, line: line)
Copy link
Preview

Copilot AI Aug 19, 2025

Choose a reason for hiding this comment

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

Using nonisolated(unsafe) is potentially dangerous as it bypasses Swift's concurrency safety checks. Consider using a safer approach like capturing self directly in the Task closure or using proper isolation.

Suggested change
try await selfReference.firstValue(file: file, line: line)
return try await Task(
timeoutInSeconds: timeoutInSeconds,
file: file,
function: function,
line: line
) {
try await self.firstValue(file: file, line: line)

Copilot uses AI. Check for mistakes.

Copy link

1 Warning
⚠️ Big PR

Generated by 🚫 Danger

Copy link

github-actions bot commented Aug 19, 2025

Public Interface

🚀 No changes affecting the public interface.

@ipavlidakis ipavlidakis changed the title Enhancement/improve task next value [Enhancement]Simplify Task.timeout and Publisher.nextValue Aug 19, 2025
@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Aug 19, 2025

SDK Size

title develop branch diff status
StreamVideo 8.18 MB 8.26 MB +77 KB 🟢
StreamVideoSwiftUI 2.29 MB 2.29 MB 0 KB 🟢
StreamVideoUIKit 2.41 MB 2.41 MB 0 KB 🟢
StreamWebRTC 9.85 MB 9.85 MB 0 KB 🟢

Copy link

Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

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

This is just a refactoring task, right? I would prefer to review and merge it after the release, since we will put other bigger stuff as well. Wdyt?

@@ -16,6 +16,10 @@ final class MockRTCAudioStore {
audioStore = RTCAudioStore(session: session)
}

deinit {
InjectedValues[\.audioStore] = .init()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a leftover from the other PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is actually here to clean the InjectedValues context when the store isn't needed any more. Now that i'm thinking out loud though, it will never be triggered as the reference is still in InjectedValues, so deinit will never be triggered. We probably need an explicit method to uninstall/dismantle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants