Skip to content
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

[ECO-5167] Make bufferingPolicy parameter optional in public API #182

Merged
merged 4 commits into from
Dec 5, 2024

Conversation

lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Dec 5, 2024

Use a default buffering policy of .unbounded. Also, I’ve added some missing bufferingPolicy parameters that for some reason I forgot to include in 20e7f5f. See commit messages for more details.

Resolves #172.

Summary by CodeRabbit

Release Notes

  • New Features

    • Simplified subscription methods for messages, reactions, typing, and occupancy, enhancing user experience.
    • Added new properties for reaction animations, improving visual feedback.
  • Bug Fixes

    • Enhanced error handling in various subscription methods to ensure robustness.
  • Documentation

    • Updated protocol methods to provide clearer subscription options and defaults.
  • Refactor

    • Streamlined method signatures across multiple components to improve clarity and usability.

`.unbounded` is the default value.
Not sure why I didn’t give these APIs such a parameter when I introduced
the public API in 20e7f5f; if there was a good reason then it’s not
obvious to me now.
When I introduced the public API in 20e7f5f, I didn’t want users to be
in a situation where there was an buffer of unbounded size growing
without them even knowing about it, and I hence forced them to be
explicit about their choice of buffering policy.

But, a couple of things:

- Marat pointed out that this makes our code examples and README look
  quite cluttered, with `bufferingPolicy` arguments all over the place.
  This distracts from demonstrating the functionality of the library.

- Swift’s own `AsyncStream` defaults to a buffering policy of
  `.unbounded`. If doing so is good enough for them, then it’s probably
  good enough for us.

So, default to `.unbounded`.

Resolves #172.
Copy link

coderabbitai bot commented Dec 5, 2024

Walkthrough

The pull request introduces significant modifications to subscription methods across various components of the SwiftUI chat application, particularly focusing on the bufferingPolicy parameter. The changes include removing the bufferingPolicy: .unbounded from subscription calls, simplifying method signatures, and enhancing the flexibility of the subscription process. Additionally, new methods are introduced to provide default behaviors for subscriptions without requiring explicit buffering policy parameters, while existing functionalities remain intact.

Changes

File Path Change Summary
Example/AblyChatExample/ContentView.swift Updated subscription methods to remove bufferingPolicy: .unbounded and added properties to Reaction.
Example/AblyChatExample/Mocks/MockClients.swift Enhanced method signatures to include bufferingPolicy for various subscription methods.
Example/AblyChatExample/Mocks/MockSubscription.swift Changed AsyncStream initialization to default buffering behavior.
Sources/AblyChat/Connection.swift Added onStatusChange() method with default buffering policy implementation.
Sources/AblyChat/DefaultMessages.swift Updated subscribeToDiscontinuities to accept bufferingPolicy.
Sources/AblyChat/DefaultOccupancy.swift Updated subscribeToDiscontinuities to accept bufferingPolicy.
Sources/AblyChat/DefaultPresence.swift Updated subscribe methods to include bufferingPolicy.
Sources/AblyChat/DefaultRoomLifecycleContributor.swift Updated subscribeToDiscontinuities to accept bufferingPolicy.
Sources/AblyChat/DefaultRoomReactions.swift Added @MainActor attribute and updated subscribeToDiscontinuities to accept bufferingPolicy.
Sources/AblyChat/DefaultTyping.swift Updated subscription methods to include bufferingPolicy.
Sources/AblyChat/EmitsDiscontinuities.swift Added new methods for subscribeToDiscontinuities with and without bufferingPolicy.
Sources/AblyChat/Messages.swift Added subscribe() method for default unbounded buffering policy.
Sources/AblyChat/Occupancy.swift Added subscribe() method for default unbounded buffering policy.
Sources/AblyChat/Presence.swift Extended Presence protocol with new subscription methods.
Sources/AblyChat/Room.swift Added onStatusChange() method for simplified status change notifications.
Sources/AblyChat/RoomFeature.swift Updated subscribeToDiscontinuities to accept bufferingPolicy.
Sources/AblyChat/RoomReactions.swift Added subscribe() method for default unbounded buffering policy.
Sources/AblyChat/Typing.swift Added subscribe() method for default unbounded buffering policy.
Tests/AblyChatTests/DefaultMessagesTests.swift Updated test cases to remove bufferingPolicy from subscription method calls.
Tests/AblyChatTests/DefaultRoomReactionsTests.swift Updated test cases to remove bufferingPolicy from subscription method calls.
Tests/AblyChatTests/DefaultRoomTests.swift Updated onStatusChange method call to remove bufferingPolicy.
Tests/AblyChatTests/IntegrationTests.swift Updated subscription calls to remove bufferingPolicy.
Tests/AblyChatTests/Mocks/MockFeatureChannel.swift Updated subscribeToDiscontinuities to accept bufferingPolicy.

Assessment against linked issues

Objective Addressed Explanation
All subscription methods should contain a method without bufferingPolicy parameter. (#172, ECO-5167)
Simplify the API by reducing noise from default parameters. (#172, ECO-5167)

🐰 In a chat where bunnies play,
Buffers now have found their way.
With simpler calls, we hop and cheer,
Our messages flow without a fear!
Subscription's light, oh what a delight,
In this code, everything feels just right! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (4)
Sources/AblyChat/RoomReactions.swift (1)

7-11: LGTM! Consider enhancing the documentation.

The new protocol method addition perfectly aligns with the PR objective of making bufferingPolicy optional. The documentation clearly explains the relationship with the original method.

Consider adding a code example to the documentation to show the simplified usage:

 /// Same as calling ``subscribe(bufferingPolicy:)`` with ``BufferingPolicy.unbounded``.
 ///
 /// The `RoomReactions` protocol provides a default implementation of this method.
+///
+/// Example usage:
+/// ```swift
+/// let subscription = await reactions.subscribe()
+/// ```
 func subscribe() async -> Subscription<Reaction>
Sources/AblyChat/DefaultRoomLifecycleContributor.swift (1)

Line range hint 52-58: Consider making subscribeToState() consistent with the new pattern.

While outside the immediate scope of this PR, the subscribeToState() method still uses a hardcoded .unbounded buffering policy. Consider making it consistent with the new pattern by:

  1. Adding a parameter for bufferingPolicy
  2. Providing a convenience method with default .unbounded
-internal func subscribeToState() async -> Subscription<ARTChannelStateChange> {
+internal func subscribeToState(bufferingPolicy: BufferingPolicy = .unbounded) async -> Subscription<ARTChannelStateChange> {
     // TODO: clean up old subscriptions (https://github.com/ably-labs/ably-chat-swift/issues/36)
-    let subscription = Subscription<ARTChannelStateChange>(bufferingPolicy: .unbounded)
+    let subscription = Subscription<ARTChannelStateChange>(bufferingPolicy: bufferingPolicy)
     underlyingChannel.on { subscription.emit($0) }
     return subscription
 }
Tests/AblyChatTests/DefaultRoomReactionsTests.swift (1)

Line range hint 76-76: Update subscribeToDiscontinuities test to include bufferingPolicy.

The test for subscribeToDiscontinuities should be updated to include the bufferingPolicy parameter to match the implementation changes in DefaultOccupancy.swift.

Apply this diff to fix the test:

-        let messagesDiscontinuitySubscription = await roomReactions.subscribeToDiscontinuities()
+        let messagesDiscontinuitySubscription = await roomReactions.subscribeToDiscontinuities(bufferingPolicy: .unbounded)
Sources/AblyChat/Messages.swift (1)

5-8: Documentation could be more descriptive

While the documentation is accurate, it could be enhanced to:

  1. Explain why .unbounded is the default choice
  2. Mention any performance implications
  3. Add a code example showing usage

Here's a suggested enhancement:

- /// Same as calling ``subscribe(bufferingPolicy:)`` with ``BufferingPolicy.unbounded``.
- ///
- /// The `Messages` protocol provides a default implementation of this method.
+ /// Subscribes to messages with an unbounded buffering policy.
+ ///
+ /// This method provides a simplified API for common use cases where message buffering
+ /// is not a concern. It uses `.unbounded` policy which stores all messages in memory
+ /// until they are consumed.
+ ///
+ /// Example usage:
+ /// ```swift
+ /// let subscription = try await messages.subscribe()
+ /// for await message in subscription {
+ ///     // Process message
+ /// }
+ /// ```
+ ///
+ /// The `Messages` protocol provides a default implementation of this method.
+ ///
+ /// - Returns: A `MessageSubscription` that can be used to receive messages.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2d7f42a and 403292c.

📒 Files selected for processing (23)
  • Example/AblyChatExample/ContentView.swift (6 hunks)
  • Example/AblyChatExample/Mocks/MockClients.swift (5 hunks)
  • Example/AblyChatExample/Mocks/MockSubscription.swift (1 hunks)
  • Sources/AblyChat/Connection.swift (1 hunks)
  • Sources/AblyChat/DefaultMessages.swift (1 hunks)
  • Sources/AblyChat/DefaultOccupancy.swift (1 hunks)
  • Sources/AblyChat/DefaultPresence.swift (3 hunks)
  • Sources/AblyChat/DefaultRoomLifecycleContributor.swift (1 hunks)
  • Sources/AblyChat/DefaultRoomReactions.swift (1 hunks)
  • Sources/AblyChat/DefaultTyping.swift (2 hunks)
  • Sources/AblyChat/EmitsDiscontinuities.swift (1 hunks)
  • Sources/AblyChat/Messages.swift (1 hunks)
  • Sources/AblyChat/Occupancy.swift (1 hunks)
  • Sources/AblyChat/Presence.swift (1 hunks)
  • Sources/AblyChat/Room.swift (1 hunks)
  • Sources/AblyChat/RoomFeature.swift (1 hunks)
  • Sources/AblyChat/RoomReactions.swift (1 hunks)
  • Sources/AblyChat/Typing.swift (1 hunks)
  • Tests/AblyChatTests/DefaultMessagesTests.swift (2 hunks)
  • Tests/AblyChatTests/DefaultRoomReactionsTests.swift (1 hunks)
  • Tests/AblyChatTests/DefaultRoomTests.swift (1 hunks)
  • Tests/AblyChatTests/IntegrationTests.swift (6 hunks)
  • Tests/AblyChatTests/Mocks/MockFeatureChannel.swift (1 hunks)
🔇 Additional comments (33)
Sources/AblyChat/Presence.swift (3)

85-88: LGTM: Addition of Default 'subscribe' Methods Enhances Usability

The inclusion of the overloaded subscribe methods without the bufferingPolicy parameter simplifies the API and improves usability by providing default behavior.


90-93: LGTM: Overloaded Methods for Multiple Events Improve API Flexibility

Adding subscribe methods that accept an array of PresenceEventType without requiring a bufferingPolicy enhances the flexibility and convenience of the API.


97-105: LGTM: Default Implementations Correctly Delegate to Parameterized Methods

The default implementations in the Presence extension correctly delegate to the parameterized methods using .unbounded buffering policy, ensuring consistent behavior.

Sources/AblyChat/Typing.swift (2)

5-8: LGTM: Addition of Default 'subscribe' Method Simplifies API

Introducing the subscribe() method without a bufferingPolicy parameter enhances usability by allowing users to subscribe with default settings.


15-19: LGTM: Default Implementation Ensures Consistent Behavior

The default implementation of subscribe() in the Typing extension correctly forwards the call to subscribe(bufferingPolicy: .unbounded), maintaining consistent behavior across the API.

Sources/AblyChat/EmitsDiscontinuities.swift (1)

20-24: LGTM: Default Implementation Appropriately Delegates Calls

The extension's subscribeToDiscontinuities() method correctly delegates to subscribeToDiscontinuities(bufferingPolicy: .unbounded), ensuring default behavior is applied consistently.

Sources/AblyChat/Occupancy.swift (2)

5-8: LGTM: Added Default 'subscribe' Method Enhances API Convenience

The new subscribe() method without a bufferingPolicy parameter simplifies the subscription process, making the API more user-friendly.


13-17: LGTM: Extension Provides Correct Default Implementation

The default implementation in the Occupancy extension appropriately calls subscribe(bufferingPolicy: .unbounded), ensuring consistent default behavior.

Sources/AblyChat/RoomReactions.swift (1)

13-16: LGTM! Clean implementation of the default behavior.

The extension provides a straightforward implementation that maintains the expected behavior while simplifying the API.

Tests/AblyChatTests/Mocks/MockFeatureChannel.swift (1)

18-22: LGTM! Implementation correctly mirrors the real component.

The mock implementation properly accepts and uses the bufferingPolicy parameter. Note that the subscription cleanup TODO is tracked in issue #36 and is unrelated to this PR's scope.

Sources/AblyChat/DefaultRoomLifecycleContributor.swift (1)

Line range hint 21-26: LGTM! Implementation correctly uses the provided bufferingPolicy.

The changes align with the PR objective and maintain consistency with other components.

Sources/AblyChat/Connection.swift (2)

8-12: LGTM! Well-documented protocol addition.

The new protocol method is well-documented, clearly indicating its relationship to the original method and default implementation.


14-17: LGTM! Clean default implementation.

The extension provides a clean implementation that correctly forwards to the original method with .unbounded buffering policy, aligning with the PR objectives.

Tests/AblyChatTests/DefaultRoomReactionsTests.swift (1)

58-58: LGTM! Test updated to use new API.

Test correctly uses the new subscribe method without bufferingPolicy parameter, aligning with the PR objectives.

Tests/AblyChatTests/DefaultMessagesTests.swift (1)

20-20: LGTM! Test cases updated to use simplified API

The test cases have been appropriately updated to use the new subscribe() method without the bufferingPolicy parameter. This change aligns with making the parameter optional and defaulting to .unbounded.

Also applies to: 59-59

Sources/AblyChat/Messages.swift (1)

14-18: LGTM! Clean implementation of default subscription

The extension provides a clean implementation of the simplified API while maintaining full functionality through the original method. This is a good solution for providing default parameter values in Swift protocols.

Sources/AblyChat/DefaultRoomReactions.swift (1)

83-84: LGTM: Method signature and implementation are correct.

The change properly forwards the bufferingPolicy parameter to the feature channel's implementation.

Sources/AblyChat/DefaultTyping.swift (2)

25-25: LGTM: Subscription creation with buffering policy is correct.

The implementation properly initializes the subscription with the provided buffering policy while maintaining the existing robust error handling and retry mechanism.


163-164: LGTM: Method signature and implementation are correct.

The change properly forwards the bufferingPolicy parameter to the feature channel's implementation.

Example/AblyChatExample/Mocks/MockClients.swift (1)

147-147: LGTM: Mock implementations consistently updated.

All mock implementations have been consistently updated to include the bufferingPolicy parameter, maintaining API compatibility. The use of fatalError("Not yet implemented") is appropriate for mock objects in example/testing code.

Also applies to: 198-198, 247-247, 343-343, 347-347, 351-351, 386-386

Sources/AblyChat/Room.swift (2)

17-20: LGTM: Well-documented protocol method addition

The new method provides a simpler API by defaulting to .unbounded buffering policy, which aligns with the PR objectives.


26-30: LGTM: Clean default implementation

The protocol extension provides a clean default implementation that maintains backward compatibility while simplifying the API.

Sources/AblyChat/DefaultPresence.swift (3)

Line range hint 167-177: LGTM: Proper integration of bufferingPolicy parameter

The method correctly integrates the bufferingPolicy parameter while maintaining existing logging and error handling.


Line range hint 181-193: LGTM: Consistent implementation for multi-event subscription

The implementation maintains consistency with the single-event subscription method and properly handles the bufferingPolicy parameter.


197-199: LGTM: Proper forwarding of bufferingPolicy

The method correctly forwards the bufferingPolicy parameter to the feature channel's discontinuities subscription.

Sources/AblyChat/DefaultMessages.swift (1)

112-114: LGTM: Consistent implementation of bufferingPolicy parameter

The method maintains consistency with other components by properly handling the bufferingPolicy parameter.

Example/AblyChatExample/ContentView.swift (5)

172-172: LGTM: Simplified subscription call by removing explicit bufferingPolicy.

The change aligns with making the bufferingPolicy parameter optional in the public API, defaulting to .unbounded.


192-192: LGTM: Simplified reactions subscription.

Removed explicit bufferingPolicy parameter, utilizing the default .unbounded value.


222-222: LGTM: Simplified typing subscription.

Removed explicit bufferingPolicy parameter, utilizing the default .unbounded value.


244-244: LGTM: Simplified occupancy subscription.

Removed explicit bufferingPolicy parameter, utilizing the default .unbounded value.


253-253: LGTM: Simplified status change subscriptions.

Both onStatusChange() calls now use the default .unbounded buffering policy, making the API more concise.

Also applies to: 266-266

Tests/AblyChatTests/IntegrationTests.swift (1)

87-87: LGTM: Updated test cases to use simplified subscription API.

Test cases have been properly updated to reflect the API changes where bufferingPolicy parameter is now optional. The changes maintain test coverage while using the new simplified API.

Also applies to: 101-101, 111-111, 155-155, 173-173, 246-246

Tests/AblyChatTests/DefaultRoomTests.swift (1)

287-287: LGTM: Updated test to use simplified onStatusChange API.

Test case properly updated to use the new method signature without the bufferingPolicy parameter.

Sources/AblyChat/EmitsDiscontinuities.swift Show resolved Hide resolved
Sources/AblyChat/DefaultOccupancy.swift Show resolved Hide resolved
Sources/AblyChat/RoomFeature.swift Show resolved Hide resolved
Copy link
Collaborator

@maratal maratal left a comment

Choose a reason for hiding this comment

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

LGTM

@lawrence-forooghian lawrence-forooghian merged commit d6adda5 into main Dec 5, 2024
12 checks passed
@lawrence-forooghian lawrence-forooghian deleted the 172-subscribe-without-buffering-policy branch December 5, 2024 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Consider using bufferingPolicy default value .unbounded
2 participants