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

Prevent infinite loop in Command::Base#step & add configurable wait time #217

Merged
merged 5 commits into from
Aug 27, 2024

Conversation

zzaakiirr
Copy link
Contributor

@zzaakiirr zzaakiirr commented Jul 22, 2024

What does this PR do?

This PR improves Command::Base#step method

Summary by CodeRabbit

  • New Features

    • Enhanced retry mechanism in the command execution process, allowing users to define the maximum number of retries and wait time between attempts.
    • Added a method to suppress console output during command execution, improving control over logging and user interface cleanliness.
  • Bug Fixes

    • Improved test coverage for the retry logic, ensuring reliable behavior in various scenarios.
  • Documentation

    • Updated configuration for RSpec tests to enforce better organization and readability by limiting nested groups.

Copy link

coderabbitai bot commented Jul 22, 2024

Walkthrough

This update introduces enhancements to the codebase, including a new RSpec linting configuration, improvements to the step method in the Command::Base class, and the addition of a helper method to manage console output during tests. These modifications improve the organization and usability of tests, aiming for a more maintainable code structure.

Changes

File Change Summary
.rubocop.yml Added configuration for RSpec/NestedGroups rule to limit nested groups to 5, improving test organization.
lib/command/base.rb Modified step method to include max_retry_count and wait parameters, allowing customizable retry behavior.
spec/command/base_spec.rb Introduced tests for #step method, validating retry logic and configurations for retry_on_failure and max_retry_count.
spec/support/command_helpers.rb Added suppress_output method to temporarily redirect output, enhancing control during testing.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant CommandBase

    Caller->>CommandBase: Call #step(message, options)
    alt retries enabled
        loop until max_retry_count
            CommandBase->>CommandBase: Execute block
            alt success
                CommandBase-->>Caller: Return result
            else failure
                CommandBase->>CommandBase: Increment run_count
            end
        end
    else retries disabled
        CommandBase->>CommandBase: Execute block once
        CommandBase-->>Caller: Return result
    end
Loading

🐰 In fields of green, with hops so bright,
New methods come, a pure delight!
With retries set and outputs tamed,
Our tests are clean, our code is famed!
So let us cheer for changes grand,
A bouncy leap, we take a stand! 🐇


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>.
    • 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 show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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.

@zzaakiirr zzaakiirr force-pushed the 216-prevent-infinite-loop-for-command-step-method branch from 65b24a2 to 9c921c1 Compare July 22, 2024 14:50
@zzaakiirr
Copy link
Contributor Author

@coderabbitai review

Copy link

coderabbitai bot commented Jul 22, 2024

Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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, codebase verification and nitpick comments (1)
lib/command/base.rb (1)

486-486: Enhance documentation for new parameters.

The new parameters max_retry_count and wait should be documented in the method's docstring to clarify their purpose and usage.

# Adds a step with a message, retries on failure if specified.
# @param message [String] the message to display
# @param abort_on_error [Boolean] whether to abort on error
# @param retry_on_failure [Boolean] whether to retry on failure
# @param max_retry_count [Integer] the maximum number of retries
# @param wait [Integer] the duration to wait between retries (in seconds)
def step(message, abort_on_error: true, retry_on_failure: false, max_retry_count: 5, wait: 1)
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 594b706 and 9c921c1.

Files selected for processing (4)
  • .rubocop.yml (1 hunks)
  • lib/command/base.rb (1 hunks)
  • spec/command/base_spec.rb (1 hunks)
  • spec/support/command_helpers.rb (1 hunks)
Additional comments not posted (4)
.rubocop.yml (1)

23-26: LGTM! The new configuration for RSpec/NestedGroups is correct.

The configuration enables the rule and sets the maximum allowed nested groups to 5, which helps improve test organization and maintainability.

spec/command/base_spec.rb (2)

1-12: LGTM! The initial setup and subject definition are appropriate.

The setup and subject definition correctly prepare the test environment for testing the Command::Base class.


14-60: LGTM! The tests for the step method are well-structured and cover important edge cases.

The tests ensure that the retry logic works correctly with different configurations. Consider adding tests for configurable wait times to further enhance coverage.

spec/support/command_helpers.rb (1)

206-214: LGTM! The suppress_output method is well-implemented.

The method correctly captures the original streams, replaces them with temporary files, and ensures that the original streams are restored after the block has executed, even if an error occurs.

lib/command/base.rb Outdated Show resolved Hide resolved
lib/command/base.rb Outdated Show resolved Hide resolved
@zzaakiirr zzaakiirr force-pushed the 216-prevent-infinite-loop-for-command-step-method branch from 9c921c1 to 15baea1 Compare July 22, 2024 17:50
@zzaakiirr zzaakiirr marked this pull request as ready for review July 22, 2024 17:57
@zzaakiirr zzaakiirr requested a review from rafaelgomesxyz July 22, 2024 17:57
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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9c921c1 and 15baea1.

Files selected for processing (4)
  • .rubocop.yml (1 hunks)
  • lib/command/base.rb (1 hunks)
  • spec/command/base_spec.rb (1 hunks)
  • spec/support/command_helpers.rb (1 hunks)
Files skipped from review as they are similar to previous changes (4)
  • .rubocop.yml
  • lib/command/base.rb
  • spec/command/base_spec.rb
  • spec/support/command_helpers.rb

@zzaakiirr zzaakiirr linked an issue Jul 22, 2024 that may be closed by this pull request
Copy link
Collaborator

@rafaelgomesxyz rafaelgomesxyz left a comment

Choose a reason for hiding this comment

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

Hm, I'm not sure that we want to do this. There are some cases where step may fail, but we do want it to keep retrying infinitely, because it will eventually succeed. I'll see if I can locate those cases and what can be done about them, otherwise this would be a breaking change.

@zzaakiirr
Copy link
Contributor Author

Hm, I'm not sure that we want to do this. There are some cases where step may fail, but we do want it to keep retrying infinitely, because it will eventually succeed. I'll see if I can locate those cases and what can be done about them, otherwise this would be a breaking change.

@rafaelgomesxyz We can set Float::INFINITY as default value for max_retry_count option, WDYT?

def step(message, abort_on_error: true, retry_on_failure: false, max_retry_count: Float::INFINITY, wait: 1)

@borela borela requested a review from rafaelgomesxyz July 24, 2024 11:31
Copy link
Collaborator

@rafaelgomesxyz rafaelgomesxyz left a comment

Choose a reason for hiding this comment

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

@zzaakiirr Setting Float::INFINITY as the default value makes it so that this PR doesn't really change anything.

Let's leave this on hold for a bit, I'll get back to it in a few days.

@zzaakiirr
Copy link
Contributor Author

zzaakiirr commented Jul 25, 2024

Setting Float::INFINITY as the default value makes it so that this PR doesn't really change anything.

@rafaelgomesxyz Yes, it doesn't change current behaviour, but method becomes more flexible - we already have issue where we can profit from configurable wait time & retry count - we shouldn't wait infinite time if domain update fails, it's better to fail with error, IMHO

Copy link
Collaborator

@rafaelgomesxyz rafaelgomesxyz left a comment

Choose a reason for hiding this comment

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

Let's proceed with this.

I've merged some changes to Command::Base#step to main, but they shouldn't conflict with yours. Still, it's good to rebase.

spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
lib/command/base.rb Outdated Show resolved Hide resolved
lib/command/base.rb Outdated Show resolved Hide resolved
lib/command/base.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Show resolved Hide resolved
@zzaakiirr zzaakiirr force-pushed the 216-prevent-infinite-loop-for-command-step-method branch from 15baea1 to ccf58b9 Compare August 22, 2024 13:12
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: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 15baea1 and ccf58b9.

Files selected for processing (4)
  • .rubocop.yml (1 hunks)
  • lib/command/base.rb (1 hunks)
  • spec/command/base_spec.rb (1 hunks)
  • spec/support/command_helpers.rb (1 hunks)
Additional comments not posted (8)
.rubocop.yml (1)

24-26: LGTM! Enabling RSpec/NestedGroups with a limit of 5.

This change promotes better readability and maintainability of test code by enforcing a structure on nested example groups.

spec/command/base_spec.rb (5)

7-7: Consider using let for command declaration.

The command is not being tested directly, so consider using let instead of subject.


27-27: Nitpick: Use parentheses for expect arguments.

Consider using parentheses for better readability:

        expect(run_count).to eq(3)

31-31: Clarify variable naming for options.

Consider using a more descriptive variable name like options_with_max_retry_count to avoid confusion.


41-41: Nitpick: Use parentheses for expect arguments.

Consider using parentheses for better readability:

          expect(run_count).to eq(1 + 1) # 1 run and 1 retry after fail

57-57: Nitpick: Use parentheses for expect arguments.

Consider using parentheses for better readability:

        expect(run_count).to eq(1)
spec/support/command_helpers.rb (1)

210-218: LGTM! Suppressing output with suppress_output.

The suppress_output method is well-implemented, effectively managing console output during tests.

lib/command/base.rb (1)

477-477: Verify default values for max_retry_count and wait.

The default values for max_retry_count (1000) and wait (1) should be reviewed to ensure they align with expected use cases. Consider the feedback from reviewers about setting a higher default for max_retry_count to accommodate longer wait times.

Run the following script to verify the usage of step method and ensure that the default values align with the expected use cases:

Verification successful

Default Values for max_retry_count and wait Are Appropriate

The step method is widely used across the codebase, and its behavior, including default values, is tested in spec/command/base_spec.rb. This suggests that the defaults are suitable for the expected use cases.

  • Files with step method usage:
    • spec/command/base_spec.rb
    • lib/command/delete.rb
    • lib/command/maintenance_set_page.rb
    • lib/command/run.rb
    • And others...
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `step` method and ensure the default values align with expected use cases.

# Test: Search for the `step` method usage. Expect: Occurrences should align with default values.
rg --type ruby -A 5 $'step('

Length of output: 90


Script:

#!/bin/bash
# Description: Verify the usage of `step` method and ensure the default values align with expected use cases.

# Test: Search for the `step` method usage. Expect: Occurrences should align with default values.
rg --type ruby -A 5 'step\('

Length of output: 14861

lib/command/base.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ccf58b9 and 046349f.

Files selected for processing (1)
  • spec/command/base_spec.rb (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • spec/command/base_spec.rb

@zzaakiirr zzaakiirr force-pushed the 216-prevent-infinite-loop-for-command-step-method branch from 046349f to 7c768e6 Compare August 23, 2024 09:08
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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 046349f and 7c768e6.

Files selected for processing (2)
  • lib/command/base.rb (2 hunks)
  • spec/command/base_spec.rb (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • lib/command/base.rb
  • spec/command/base_spec.rb

spec/command/base_spec.rb Outdated Show resolved Hide resolved
spec/command/base_spec.rb Outdated Show resolved Hide resolved
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: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7c768e6 and 81fdc47.

Files selected for processing (1)
  • spec/command/base_spec.rb (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • spec/command/base_spec.rb

Copy link
Collaborator

@rafaelgomesxyz rafaelgomesxyz left a comment

Choose a reason for hiding this comment

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

Thanks!

Just do one final thing before merging please: update the changelog (follow the pattern we use) to mention that we fixed a potential infinite loop that could happen in certain commands.

@zzaakiirr zzaakiirr merged commit f78251d into main Aug 27, 2024
5 checks passed
@zzaakiirr zzaakiirr deleted the 216-prevent-infinite-loop-for-command-step-method branch August 27, 2024 01:47
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.

[PROPOSAL] Add max_retry_count and wait kwargs to Command::Base#step
2 participants