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

Fix implicit attach on subscribe #1028

Merged
merged 6 commits into from
Sep 18, 2024
Merged

Conversation

sacOO7
Copy link
Collaborator

@sacOO7 sacOO7 commented Sep 16, 2024

Fixed #1027

Summary by CodeRabbit

  • New Features

    • Introduced a configurable option for channel subscriptions to control automatic attachment behavior.
    • Added a new field attachOnSubscribe in ChannelOptions to manage implicit attachment during subscriptions.
  • Bug Fixes

    • Improved control flow in subscription methods to prevent unnecessary operations when implicit attachment is disabled.
  • Tests

    • Added tests to validate subscription behavior without implicit channel attachment for both messages and presence events.

Copy link

coderabbitai bot commented Sep 16, 2024

Warning

Rate limit exceeded

@sacOO7 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 0 seconds before requesting another review.

How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Commits

Files that changed from the base of the PR and between d8181e8 and 3ecab48.

Walkthrough

The changes introduce a new configuration option, attachOnSubscribe, to the Ably library, allowing users to control whether a channel automatically attaches upon subscription. This functionality is implemented in the ChannelBase, Presence, and ChannelOptions classes, along with corresponding tests to ensure proper behavior. The modifications enhance the subscription process by enabling conditional attachment, improving the configurability of channel interactions.

Changes

Files Change Summary
lib/src/main/java/io/ably/lib/realtime/ChannelBase.java Added method attachOnSubscribeEnabled() to control channel attachment on subscription based on options.
lib/src/main/java/io/ably/lib/realtime/Presence.java Updated implicitAttachOnSubscribe to check attachOnSubscribeEnabled() before proceeding with subscription.
lib/src/main/java/io/ably/lib/types/ChannelOptions.java Introduced public field attachOnSubscribe to specify automatic attachment behavior on subscription.
lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java Added test method subscribe_without_implicit_attach to verify subscription behavior without automatic attachment.
lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java Added test method presence_subscribe_without_implicit_attach to validate presence subscription without attachment.

Assessment against linked issues

Objective Addressed Explanation
Implement the attachOnSubscribe channel option (TB4)

🐰 In the realm of code, a change takes flight,
With options for channels, oh what a delight!
Attach on subscribe, now users can choose,
A flexible path, no more to lose.
Tests are in place, to ensure it’s right,
Hopping along, our features shine bright! 🌟


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 generate interesting stats about this repository and render them as a table.
    -- @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.
Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI o1 for code reviews: OpenAI's new o1 model is being tested for generating code suggestions in code reviews.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 16, 2024 05:54 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 16, 2024 05:55 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 16, 2024 08:04 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 16, 2024 08:05 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 17, 2024 09:34 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 17, 2024 09:34 Inactive
@sacOO7 sacOO7 force-pushed the feature/attach-on-subcribe-channelOption branch from 871197b to 0436cd9 Compare September 17, 2024 09:43
@sacOO7 sacOO7 marked this pull request as ready for review September 17, 2024 09:43
@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 17, 2024 09:44 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 17, 2024 09:44 Inactive
@sacOO7 sacOO7 force-pushed the feature/attach-on-subcribe-channelOption branch from 0436cd9 to d8181e8 Compare September 17, 2024 09:47
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.

Caution

Inline review comments failed to post

Actionable comments posted: 8

Outside diff range and nitpick comments (3)
lib/src/main/java/io/ably/lib/realtime/ChannelBase.java (1)

693-701: Ensure consistent terminology in comments

The JavaDoc comment refers to channelOptions, but the code uses options. For clarity and consistency, consider updating the comment to use options to match the code.

Apply this diff to update the comment:

     /**
-     * Checks for null channelOptions and checks if options.attachOnSubscribe is true
+     * Checks for null options and checks if options.attachOnSubscribe is true
-     * Defaults to @true@ when channelOptions is null.
+     * Defaults to @true@ when options is null.
      * Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e
      */
lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java (2)

417-417: Specify generic type for List to enhance type safety

The receivedMsg list is currently declared with a raw type List<Object>. Since you're adding Boolean values, specifying the generic type as Boolean improves type safety and readability.

Apply this diff:

-List<Object> receivedMsg = new ArrayList<>();
+List<Boolean> receivedMsg = new ArrayList<>();

449-451: Update error message in catch block for clarity

The error message in the catch block refers to "init0," which may not accurately reflect the context of this test method. Consider updating the message to provide a clearer description of the exception.

Apply this diff:

-fail("init0: Unexpected exception instantiating library");
+fail("subscribe_without_implicit_attach: Unexpected exception");
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e0e2317 and 0436cd9.

Files selected for processing (5)
  • lib/src/main/java/io/ably/lib/realtime/ChannelBase.java (4 hunks)
  • lib/src/main/java/io/ably/lib/realtime/Presence.java (1 hunks)
  • lib/src/main/java/io/ably/lib/types/ChannelOptions.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java (1 hunks)
  • lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java (1 hunks)
Additional comments not posted (2)
lib/src/main/java/io/ably/lib/realtime/ChannelBase.java (2)

753-755: Duplication of conditional attach() logic

This code block duplicates the attach() logic found in other subscribe methods. Refer to the earlier refactoring suggestion to extract this logic into a common method and improve code maintainability.


789-791: Duplication of conditional attach() logic

This code block duplicates the attach() logic found in other subscribe methods. Refer to the earlier refactoring suggestion to extract this logic into a common method and improve code maintainability.

Comments failed to post (8)
lib/src/main/java/io/ably/lib/types/ChannelOptions.java (2)

48-48: Encapsulate 'attachOnSubscribe' field with getter and setter methods

Consider making the attachOnSubscribe field private and providing public getter and setter methods. This follows best practices for encapsulation and allows for additional control or validation when accessing or modifying the field.

Suggested changes:

-    public boolean attachOnSubscribe = true;
+    private boolean attachOnSubscribe = true;
+
+    public boolean isAttachOnSubscribe() {
+        return attachOnSubscribe;
+    }
+
+    public void setAttachOnSubscribe(boolean attachOnSubscribe) {
+        this.attachOnSubscribe = attachOnSubscribe;
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    private boolean attachOnSubscribe = true;

    public boolean isAttachOnSubscribe() {
        return attachOnSubscribe;
    }

    public void setAttachOnSubscribe(boolean attachOnSubscribe) {
        this.attachOnSubscribe = attachOnSubscribe;
    }

44-46: Use proper JavaDoc formatting for code references

In the JavaDoc comments, use {@code ...} for code snippets or values, and {@link ...} for method references. Replace @subscribe@ and @true@ with the appropriate JavaDoc syntax.

Suggested changes:

-     * Determines whether calling @subscribe@ on a channel or presence object should trigger an implicit attach.
-     * Defaults to @true@.
+     * Determines whether calling {@link io.ably.lib.realtime.Channel#subscribe} on a channel or presence object should trigger an implicit attach.
+     * Defaults to {@code true}.
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

     * Determines whether calling {@link io.ably.lib.realtime.Channel#subscribe} on a channel or presence object should trigger an implicit attach.
     * Defaults to {@code true}.
     * Spec: TB4, RTL7g, RTL7gh, RTP6d, RTP6e
lib/src/main/java/io/ably/lib/realtime/Presence.java (1)

311-316: Ensure channel state is checked even when attachOnSubscribe is disabled

In the modified code, when channel.attachOnSubscribeEnabled() returns false, the method exits early without checking if the channel state is failed. This omission could allow operations to proceed on a failed channel, leading to unexpected behavior or unhandled exceptions. To maintain consistent error handling, the check for channel.state == ChannelState.failed should occur regardless of the attachOnSubscribe setting.

Apply this diff to include the channel state check before returning:

 if (!channel.attachOnSubscribeEnabled()) {
+    if (channel.state == ChannelState.failed) {
+        String errorString = String.format(Locale.ROOT, "Channel %s: subscribe in FAILED channel state", channel.name);
+        Log.v(TAG, errorString);
+        ErrorInfo errorInfo = new ErrorInfo(errorString, 90001);
+        throw AblyException.fromErrorInfo(errorInfo);
+    }
     if (completionListener != null) {
         completionListener.onSuccess();
     }
     return;
 }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        if (!channel.attachOnSubscribeEnabled()) {
            if (channel.state == ChannelState.failed) {
                String errorString = String.format(Locale.ROOT, "Channel %s: subscribe in FAILED channel state", channel.name);
                Log.v(TAG, errorString);
                ErrorInfo errorInfo = new ErrorInfo(errorString, 90001);
                throw AblyException.fromErrorInfo(errorInfo);
            }
            if (completionListener != null) {
                completionListener.onSuccess();
            }
            return;
        }
lib/src/main/java/io/ably/lib/realtime/ChannelBase.java (1)

716-718: Consider refactoring to eliminate code duplication

The conditional attach() call based on attachOnSubscribeEnabled() is repeated in multiple subscribe methods. To improve maintainability and reduce duplication, consider extracting this logic into a private helper method.

Apply this diff to refactor the repeated code:

+private void attachIfNeeded() throws AblyException {
+    if (attachOnSubscribeEnabled()) {
+        attach();
+    }
+}

 public synchronized void subscribe(MessageListener listener) throws AblyException {
     Log.v(TAG, "subscribe(); channel = " + this.name);
     listeners.add(listener);
-    if (attachOnSubscribeEnabled()) {
-        attach();
-    }
+    attachIfNeeded();
 }

And similarly update the other subscribe methods to use attachIfNeeded():

 public synchronized void subscribe(String name, MessageListener listener) throws AblyException {
     Log.v(TAG, "subscribe(); channel = " + this.name + "; event = " + name);
     subscribeImpl(name, listener);
-    if (attachOnSubscribeEnabled()) {
-        attach();
-    }
+    attachIfNeeded();
 }

 public synchronized void subscribe(String[] names, MessageListener listener) throws AblyException {
     Log.v(TAG, "subscribe(); channel = " + this.name + "; (multiple events)");
     for(String name : names)
         subscribeImpl(name, listener);
-    if (attachOnSubscribeEnabled()) {
-        attach();
-    }
+    attachIfNeeded();
 }

Committable suggestion was skipped due to low confidence.

lib/src/test/java/io/ably/lib/test/realtime/RealtimeChannelTest.java (2)

420-420: Swap parameters in assertEquals method

The assertEquals method expects the expected value as the first parameter and the actual value as the second. Currently, the parameters are reversed, which can lead to confusing error messages if the test fails.

Apply the following diff to correct the parameter order:

-assertEquals(channel.state, ChannelState.initialized);
+assertEquals(ChannelState.initialized, channel.state);

Repeat this change for all instances where assertEquals is used with reversed parameters.

Also applies to: 423-423, 426-426


419-419: Clarify the reasoning behind expecting two received messages

The test expects receivedMsg.size() == 2 after publishing a message, which might be unclear to someone reading the code. Adding a comment to explain why two messages are expected can improve the test's readability and maintainability.

For example, you could add a comment:

// Expecting two callbacks: one from the wildcard subscription and one from the specific event subscription

Also applies to: 422-422, 425-425

lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java (2)

1653-1654: Fix the order of arguments in assertEquals method calls

In JUnit's assertEquals(expected, actual) method, the first argument is the expected value, and the second is the actual value. Currently, the arguments are reversed in lines 1653, 1654, 1657, and 1658, which can lead to misleading assertion messages if a test fails.

Apply this diff to correct the assertEquals calls:

-        assertEquals(completionWaiter.successCount, 1);
+        assertEquals(1, completionWaiter.successCount);
-        assertEquals(channel.state, ChannelState.initialized);
+        assertEquals(ChannelState.initialized, channel.state);

-        assertEquals(completionWaiter.successCount, 2);
+        assertEquals(2, completionWaiter.successCount);
-        assertEquals(channel.state, ChannelState.initialized);
+        assertEquals(ChannelState.initialized, channel.state);

Also applies to: 1657-1658


1649-1652: Ensure thread-safe access to receivedPresenceMsg

The receivedPresenceMsg list is accessed from multiple threads since the PresenceListener callbacks may be invoked asynchronously. As ArrayList is not thread-safe, this can lead to concurrency issues. Consider using a thread-safe collection like Collections.synchronizedList(new ArrayList<>()) or a CopyOnWriteArrayList.

Apply this diff to make receivedPresenceMsg thread-safe:

 import java.util.ArrayList;
+import java.util.Collections;
 
 ...
 
-        List<Object> receivedPresenceMsg = new ArrayList<>();
+        List<Object> receivedPresenceMsg = Collections.synchronizedList(new ArrayList<>());

Also applies to: 1666-1675

@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 17, 2024 09:48 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 17, 2024 09:48 Inactive
@sacOO7 sacOO7 requested a review from ttypic September 17, 2024 09:50
@sacOO7 sacOO7 force-pushed the feature/attach-on-subcribe-channelOption branch from 9728f6b to de01e91 Compare September 17, 2024 10:41
@github-actions github-actions bot temporarily deployed to staging/pull/1028/features September 17, 2024 10:41 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/1028/javadoc September 17, 2024 10:42 Inactive
Copy link
Contributor

@ttypic ttypic left a comment

Choose a reason for hiding this comment

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

LGTM

@sacOO7
Copy link
Collaborator Author

sacOO7 commented Sep 18, 2024

LGTM

Thanks for the review

@sacOO7 sacOO7 merged commit 7a360ae into main Sep 18, 2024
6 of 10 checks passed
@sacOO7 sacOO7 deleted the feature/attach-on-subcribe-channelOption branch September 18, 2024 10:32
@coderabbitai coderabbitai bot mentioned this pull request Sep 18, 2024
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.

Implement the attachOnSubscribe channel option (TB4)
2 participants