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-4987] Implement lifecycle behaviour that relates to an ongoing operation #85

Merged

Conversation

lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Oct 15, 2024

Does a bunch of groundwork, and then implements spec points CHA-RL1d and CHA-RL3c. See commit mesages for more details.

Resolves #52.

Summary by CodeRabbit

  • New Features

    • Enhanced room lifecycle management with a new status tracking system.
    • Improved handling of contributor states and operations, including attach, detach, and release.
  • Bug Fixes

    • Refined logic for managing pending events and error handling during contributor detachment.
  • Tests

    • Updated tests to reflect changes in room lifecycle operations and added new test cases for improved coverage and error handling.

I’ve just moved things around and added some MARK: sections.
This is currently a copy of RoomLifecycle, but will expand to store
additional manager state related to each status case.
Remove the temporary hasOperationInProgress stored property added in
b6c3ddb.

It seems to me, at least based on what I’ve implemented so far, that you
have an operation in progress if and only if you’re in a certain status
case, so I’ve encoded this constraint in the Status type. Might turn out
this is false and needs to be revisited later.

The operation IDs will be used in an upcoming commit, to allow one
operation to wait for the completion of another.
We’ll use this mechanism to implement CHA-RL1d and CHA-RL3c for #52.
Allow tests to find out that one lifecycle operation is waiting for
another. This will be needed for testing spec point CHA-RL1d, which
states that an ATTACH operation should wait for an in-progress operation
to complete before proceeding; I couldn’t think of any way to test this
(e.g. looking for some side effect) with the information that we
currently have, hence this testing API.
Will use this in some upcoming tests. Intended for use with the API
added in 57e1459.
(From the same spec as referenced in 25e5052.)
(From the same spec as referenced in 25e5052.)

Resolves #52.
Copy link

coderabbitai bot commented Oct 15, 2024

Walkthrough

The changes in this pull request primarily focus on the RoomLifecycleManager class, introducing a new Status enum to manage room lifecycle states and enhancing contributor state management. Key methods have been updated to incorporate this enum, and new structures for operation result tracking have been added. The corresponding test file has also been modified to reflect these changes, with updated parameters and new test cases to ensure proper functionality and error handling.

Changes

File Change Summary
Sources/AblyChat/RoomLifecycleManager.swift Introduced Status enum, updated methods to use this enum, refined state transition logic, added OperationResultContinuations structure, and improved error handling.
Tests/AblyChatTests/RoomLifecycleManagerTests.swift Updated createManager parameters, added new test case for operation completion, refined tests for status handling, and enhanced error handling in tests.

Assessment against linked issues

Objective Addressed Explanation
Implement lifecycle behaviour that relates to an ongoing operation (#52)

Possibly related issues

Possibly related PRs

Suggested reviewers

  • maratal
  • umair-ably

Poem

In the room where we chat,
Lifecycle dances, oh so sprat!
States now managed with great flair,
Attach, detach, we handle with care.
With tests that verify our way,
Hooray for changes, hip-hip-hooray! 🐇✨


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: 2

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

52-52: Consider making the status property private(set) if external read access is needed

The status property is declared as a mutable private variable. If it needs to be read externally but only modified within the RoomLifecycleManager, consider changing it to private(set) to allow external read access while preventing external modifications.

Apply this change:

-private var status: Status
+private(set) var status: Status

379-380: Clarify the definition of hasOperationInProgress

The comment above hasOperationInProgress mentions uncertainty about its exact meaning. For maintainability, consider clarifying when an operation is considered in progress and when it is completed. This will help other developers understand the flow and prevent potential misuse of the property.


478-483: Handle specific errors instead of catching all errors

In the performAnOperation method, you're catching all errors but rethrowing them immediately. Consider catching specific error types or removing the do-catch block if it's not adding value. This can make error handling clearer and prevent unintended swallowing of errors.


718-719: Redundant comment in RELEASE operation

The comment // CHA-RL3c is repeated above and below the changeStatus call. Consider removing the redundant comment to improve code readability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2e4dc92 and ce37606.

📒 Files selected for processing (2)
  • Sources/AblyChat/RoomLifecycleManager.swift (13 hunks)
  • Tests/AblyChatTests/RoomLifecycleManagerTests.swift (12 hunks)
🧰 Additional context used
📓 Learnings (3)
📓 Common learnings
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:0-0
Timestamp: 2024-09-18T18:34:37.252Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #49.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:0-0
Timestamp: 2024-10-08T15:58:47.376Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #49.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:627-631
Timestamp: 2024-10-01T12:55:21.968Z
Learning: The closure `detachImpl` in `RoomLifecycleManagerTests.swift` functions as intended without external state variables to track invocation count.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:627-631
Timestamp: 2024-10-08T15:58:47.376Z
Learning: The closure `detachImpl` in `RoomLifecycleManagerTests.swift` functions as intended without external state variables to track invocation count.
Sources/AblyChat/RoomLifecycleManager.swift (4)
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:0-0
Timestamp: 2024-09-18T18:34:37.252Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #49.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Sources/AblyChat/RoomLifecycleManager.swift:0-0
Timestamp: 2024-10-08T15:58:47.376Z
Learning: In `RoomLifecycleManager`, handling of unexpected contributor states after attach failure will be addressed in issue #49.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Sources/AblyChat/RoomLifecycleManager.swift:217-220
Timestamp: 2024-10-01T19:44:34.032Z
Learning: In `RoomLifecycleManager`, handling of missing `stateChange.reason` when `stateChange.resumed` is `false` is being tracked in issue #74. Future reviews should be aware of this planned work.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Sources/AblyChat/RoomLifecycleManager.swift:217-220
Timestamp: 2024-10-08T15:58:47.376Z
Learning: In `RoomLifecycleManager`, handling of missing `stateChange.reason` when `stateChange.resumed` is `false` is being tracked in issue #74. Future reviews should be aware of this planned work.
Tests/AblyChatTests/RoomLifecycleManagerTests.swift (10)
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:627-631
Timestamp: 2024-10-08T15:58:47.376Z
Learning: The closure `detachImpl` in `RoomLifecycleManagerTests.swift` functions as intended without external state variables to track invocation count.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:627-631
Timestamp: 2024-10-01T12:55:21.968Z
Learning: The closure `detachImpl` in `RoomLifecycleManagerTests.swift` functions as intended without external state variables to track invocation count.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:335-335
Timestamp: 2024-09-23T19:56:39.435Z
Learning: In Swift Testing, test method names do not need to start with `test`.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:499-504
Timestamp: 2024-10-01T12:47:28.179Z
Learning: In test closures, parameters like `callCount` may be used to track invocation counts correctly across invocations.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:499-504
Timestamp: 2024-10-08T15:58:47.376Z
Learning: In test closures, parameters like `callCount` may be used to track invocation counts correctly across invocations.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#54
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:335-335
Timestamp: 2024-10-08T15:58:47.376Z
Learning: In Swift Testing, test method names do not need to start with `test`.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:941-941
Timestamp: 2024-10-01T19:46:16.467Z
Learning: When a TODO comment references an existing GitHub issue, it's acceptable to leave it in the code without requesting its removal.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:941-941
Timestamp: 2024-10-08T15:58:47.376Z
Learning: When a TODO comment references an existing GitHub issue, it's acceptable to leave it in the code without requesting its removal.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:836-836
Timestamp: 2024-10-01T19:46:04.461Z
Learning: Before suggesting the removal of TODO comments, check if they reference existing GitHub issues that track the pending work.
Learnt from: lawrence-forooghian
PR: ably-labs/ably-chat-swift#67
File: Tests/AblyChatTests/RoomLifecycleManagerTests.swift:836-836
Timestamp: 2024-10-08T15:58:47.376Z
Learning: Before suggesting the removal of TODO comments, check if they reference existing GitHub issues that track the pending work.
🔇 Additional comments (15)
Sources/AblyChat/RoomLifecycleManager.swift (3)

246-253: Potential concurrency issue in changeStatus method

In the changeStatus(to:) method, the status is updated, and then emitStatusChange is called to notify subscribers. Since RoomLifecycleManager is an actor, these operations are isolated. However, ensure that any asynchronous calls within emitStatusChange do not introduce concurrency issues or race conditions.


435-438: Verify thread safety when accessing operationResultContinuations

In waitForCompletionOfOperationWithID, you modify operationResultContinuations by adding continuations. Since this structure is mutable, ensure that all accesses to it are properly isolated within the actor to prevent race conditions.


Line range hint 563-567: Confirm the timing of emitPendingDiscontinuityEvents

In bodyOfAttachOperation, the call to emitPendingDiscontinuityEvents is preceded by a TODO comment about whether it's part of the ATTACH operation. Clarify the sequence according to the specification to ensure correct behavior.

Tests/AblyChatTests/RoomLifecycleManagerTests.swift (12)

31-31: Update parameter to accept Status instead of RoomLifecycle.

Changing the parameter forTestingWhatHappensWhenCurrentlyIn to accept RoomLifecycleManager<MockRoomLifecycleContributor>.Status? provides a more precise representation of the manager's state in tests. This enhances the clarity and specificity of the test setups.


100-102: Consistent use of updated Status in test initialization.

The test attach_whenReleasing now correctly initializes the manager with the .releasing status using the updated parameter. This ensures that the test accurately reflects the releasing state.


128-174: Well-structured test for operation sequencing with concurrent operations.

The new test attach_ifOtherOperationInProgress_waitsForItToComplete effectively verifies that an ATTACH operation waits for a pending operation to complete, as specified in CHA-RL1d. The use of mock operations and async tasks is appropriate and clearly demonstrates the intended behavior.


443-445: Proper initialization of manager state in detach_whenReleasing.

Updating the manager initialization to use the .releasing status ensures that the detach_whenReleasing test accurately reflects the intended state when testing error handling.


653-697: Accurate test for handling concurrent RELEASE operations.

The test release_whenReleasing correctly verifies that a second RELEASE operation waits for the first to complete, adhering to CHA-RL3c. The implementation effectively checks that the second release does not duplicate work and that operations are properly sequenced.


850-853: Recording pending discontinuity events during ongoing operations.

In contributorUpdate_withResumedFalse_withOperationInProgress_recordsPendingDiscontinuityEvent, the manager correctly records a pending discontinuity event when an update occurs during an operation. This aligns with CHA-RL4a3 and ensures that events are not lost.


881-884: Immediate discontinuity handling without ongoing operations.

The test contributorUpdate_withResumedTrue_withNoOperationInProgress_emitsDiscontinuityEvent properly checks that discontinuity events are emitted immediately when no operation is in progress, fulfilling CHA-RL4a4.


912-915: Correct handling of ATTACHED events with resumed false during operations.

The test contributorAttachEvent_withResumeFalse_withOperationInProgress_recordsPendingDiscontinuityEvent ensures that the manager records discontinuity events appropriately, adhering to CHA-RL4b1.


947-950: Handling contributor failure events without operations in progress.

In contributorFailedEvent_withNoOperationInProgress, the manager transitions to a failed state upon receiving a contributor's FAILED event, which is consistent with the specification. Detaching all contributors in response is appropriate.


982-982: Ensuring room transitions to ATTACHED when all contributors are attached.

The test contributorAttachedEvent_withNoOperationInProgress_roomNotAttached_allContributorsAttached correctly verifies that the room transitions to ATTACHED when all contributors are in the ATTACHED state, as specified in CHA-RL4b8.


Line range hint 1015-1041: Validating that room does not transition if not all contributors are attached.

The test contributorAttachedEvent_withNoOperationInProgress_roomNotAttached_notAllContributorsAttached appropriately checks that the room does not transition to ATTACHED if any contributor is not attached.


1049-1052: Proper handling of SUSPENDED events without ongoing operations.

The test contributorSuspendedEvent_withNoOperationInProgress confirms that the manager transitions the room to SUSPENDED when a contributor enters the SUSPENDED state, which aligns with CHA-RL4b9.

Sources/AblyChat/RoomLifecycleManager.swift Show resolved Hide resolved
Sources/AblyChat/RoomLifecycleManager.swift Show resolved Hide resolved
Copy link
Collaborator

@umair-ably umair-ably left a comment

Choose a reason for hiding this comment

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

LGTM - was hard to follow but the comments really helped! Just the one outstanding comment but more of a thought as opposed to something you need to do for this to get merged

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 lifecycle behaviour that relates to an ongoing operation
2 participants