Skip to content

Conversation

aaguiarz
Copy link
Member

@aaguiarz aaguiarz commented Jun 13, 2025

Summary

  • adjust tuple write defaults when --max-rps is provided
  • update README with new behaviour

Testing

  • go test ./...
  • golangci-lint run ./...

https://chatgpt.com/codex/tasks/task_e_684c496919a4832281aae1a0eeb79f73

Summary by CodeRabbit

  • Documentation
    • Clarified how default values for batching and rate-limiting flags interact when using the fga tuple write command.
    • Updated descriptions for --max-tuples-per-write, --max-parallel-requests, --max-rps, and --rampup-period-in-sec to reflect new conditional defaults.
    • Simplified example usage for improved clarity.

@aaguiarz aaguiarz requested review from a team as code owners June 13, 2025 16:37
@aaguiarz aaguiarz requested a review from a team as a code owner June 13, 2025 16:37
Copy link
Contributor

coderabbitai bot commented Jun 13, 2025

## Walkthrough

The documentation and implementation for the `fga tuple write` command were updated to clarify and enforce conditional default values for the `--max-tuples-per-write`, `--max-parallel-requests`, and `--rampup-period-in-sec` flags when `--max-rps` is set. The requirement for specifying `--rampup-period-in-sec` with `--max-rps` was removed, and example usage was simplified. New constants were added to support these defaults, and validation ensures all integer flags are greater than zero if provided.

## Changes

| File(s)                   | Change Summary                                                                                      |
|--------------------------|---------------------------------------------------------------------------------------------------|
| README.md                | Clarified default behaviors for batching and rate limiting flags; simplified example command.      |
| cmd/tuple/write.go       | Added flag validation and conditional defaults based on `max-rps`; removed required-together flags.|
| internal/tuple/import.go | Added constants for default batch size, parallel requests divisor, and ramp-up period multiplier.   |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant TupleWriter

    User->>CLI: Run 'fga tuple write' with flags
    CLI->>CLI: Validate flags (must be > 0 if set)
    CLI->>CLI: Check if --max-rps is set
    alt --max-rps set & other flags omitted
        CLI->>CLI: Apply conditional defaults for omitted flags
    end
    CLI->>TupleWriter: Invoke tuple import with resolved flag values
    TupleWriter->>CLI: Return result
    CLI->>User: Output import result

Poem

In the warren of flags, defaults now align,
With max-rps set, the logic is fine.
No more must you pair rampup by hand—
The CLI’s smarter, just as planned.
So hop along, import with glee,
The tuples flow as fast as can be! 🐇


<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between cf697d9d86ffbc6597b716b4d9d31617872113af and c3b19f3bca05f56a83ba2370519e8ad62498dc6e.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `CHANGELOG.md` (1 hunks)

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* CHANGELOG.md

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (3)</summary>

* GitHub Check: Test Release Process
* GitHub Check: Tests
* GitHub Check: Analyze (go)

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=openfga/cli&utm_content=517):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `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 explain this code block.`
  -	`@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 explain its main purpose.`
  - `@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.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

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 generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this 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](https://docs.coderabbit.ai/guides/configure-coderabbit) 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](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link
Contributor

@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

🧹 Nitpick comments (3)
cmd/tuple/write.go (1)

171-174: Hard-coded magic number – promote to a named constant

40 appears out of thin air; keeping this value in sync between code and docs will be error-prone.

-		maxTuplesPerWrite = 40
+		maxTuplesPerWrite = tuple.MaxTuplesPerWriteWithMaxRPS // e.g. 40

Define tuple.MaxTuplesPerWriteWithMaxRPS next to the existing tuple.MaxTuplesPerWrite constant to make intent explicit and avoid scattering literals.

README.md (2)

674-679: Markdown list style and punctuation don’t follow project lint rules

The static analyzers flagged the asterisk list markers (*) and a missing comma.
Switch to dash markers (-) as elsewhere in the doc and add the missing comma to keep markdownlint and languagetool green.

-* `--max-tuples-per-write`: Max tuples to send in a single write (optional, default=1, or 40 if `--max-rps` is set and this flag is omitted)
-* `--max-parallel-requests`: Max requests to send in parallel (optional, default=4, or `max-rps/5` if `--max-rps` is set and this flag is omitted)
-* `--hide-imported-tuples`: When importing from a file, do not output successfully imported tuples in the command output (optional, default=false)
-* `--max-rps`: Max requests per second. When set, the CLI will ramp up requests from 1 RPS to the set value. If `--rampup-period-in-sec` is omitted it defaults to `max-rps*2`.
-* `--rampup-period-in-sec`: Time in seconds to wait between each batch of tuples when ramping up. Only used if `--max-rps` is set.
+ - `--max-tuples-per-write`: Max tuples to send in a single write (optional, default = 1, or 40 if `--max-rps` is set and this flag is omitted),
+ - `--max-parallel-requests`: Max requests to send in parallel (optional, default = 4, or `max-rps/5` if `--max-rps` is set and this flag is omitted),
+ - `--hide-imported-tuples`: When importing from a file, do not output successfully imported tuples in the command output (optional, default = false),
+ - `--max-rps`: Max requests per second. When set, the CLI will ramp up requests from 1 RPS to the set value. If `--rampup-period-in-sec` is omitted, it defaults to `max-rps*2`,
+ - `--rampup-period-in-sec`: Time in seconds to wait between each batch of tuples when ramping up. Only used if `--max-rps` is set.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~677-~677: Possible missing comma found.
Context: ...t value. If --rampup-period-in-sec is omitted it defaults to max-rps*2. * `--rampup...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~678-~678: Loose punctuation mark.
Context: ... max-rps*2. * --rampup-period-in-sec: Time in seconds to wait between each ba...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)

674-674: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


675-675: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


676-676: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


677-677: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


678-678: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


684-685: Example now relies on new defaults – clarify parallelism

The simplified example is great, but readers may wonder why the CLI still issues multiple parallel requests or writes more than one tuple per request.
Consider appending a brief note such as “(other limits will default automatically based on --max-rps as explained above)” to avoid confusion.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb88057 and 7b1d24e.

📒 Files selected for processing (2)
  • README.md (1 hunks)
  • cmd/tuple/write.go (1 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~677-~677: Possible missing comma found.
Context: ...t value. If --rampup-period-in-sec is omitted it defaults to max-rps*2. * `--rampup...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~678-~678: Loose punctuation mark.
Context: ... max-rps*2. * --rampup-period-in-sec: Time in seconds to wait between each ba...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)
README.md

674-674: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


675-675: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


676-676: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


677-677: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


678-678: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test Release Process
  • GitHub Check: Tests

@aaguiarz aaguiarz marked this pull request as draft June 13, 2025 16:45
@aaguiarz
Copy link
Member Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Jun 15, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@aaguiarz I'll review this PR for you. Let me examine the implementation and documentation changes.


🏁 Script executed:

#!/bin/bash
# First, let's examine the current state of the changed files
echo "=== README.md content (tuple write section) ==="
rg -A 50 -B 10 "fga tuple write" README.md

echo -e "\n=== cmd/tuple/write.go content ==="
cat cmd/tuple/write.go

Length of output: 17858


🏁 Script executed:

#!/bin/bash
# Let's look for existing constants and test files
echo "=== Looking for tuple-related constants ==="
rg -A 5 -B 5 "MaxTuplesPerWrite|MaxParallelRequests" 

echo -e "\n=== Looking for test files related to tuple write ==="
fd -e go -x grep -l "write.*tuple\|tuple.*write" {} \; | head -10

echo -e "\n=== Check if there are existing tests for the write command ==="
rg -A 10 -B 5 "func.*Test.*[Ww]rite" --type go

echo -e "\n=== Look for any existing magic numbers ==="
rg "40|/\s*5|\*\s*2" cmd/tuple/write.go

Length of output: 7577


🏁 Script executed:

#!/bin/bash
# Let's check the discrepancy between constants and flag defaults
echo "=== Check flag initialization in write.go ==="
rg -A 2 -B 2 "Flags\(\)\.Int.*max-parallel-requests" cmd/tuple/write.go

echo -e "\n=== Check flag initialization in delete.go ==="
rg -A 2 -B 2 "Flags\(\)\.Int.*max-parallel-requests" cmd/tuple/delete.go

echo -e "\n=== Check constants in internal/tuple/import.go ==="
rg -A 5 -B 5 "MaxParallelRequests\s*=" internal/tuple/import.go

echo -e "\n=== Let's see the git diff to understand what changed ==="
git log --oneline -5

echo -e "\n=== Check if the flag was correctly removed from MarkFlagsRequiredTogether ==="
rg -A 10 -B 5 "MarkFlagsRequiredTogether\|RequiredTogether" cmd/tuple/write.go || echo "No MarkFlagsRequiredTogether found"

Length of output: 2116


🏁 Script executed:

#!/bin/bash
# Let's check what the actual default value is for max-parallel-requests in the delete command
echo "=== Check delete command usage ==="
rg -A 5 -B 5 "tuple\.MaxParallelRequests" 

echo -e "\n=== Let's see if there are any other references to the constant ==="
rg "MaxParallelRequests" --type go

echo -e "\n=== Let's check if there are tests for the conditional logic ==="
rg -A 15 -B 5 "max-rps.*flag\|flag.*max-rps" --type go

echo -e "\n=== Check if there are any validation tests for the new logic ==="
fd "write.*test\.go" -x cat {} \;

Length of output: 12854


@aaguiarz Thank you for this improvement! The dynamic defaults feature is a great UX enhancement. I've reviewed the implementation and have several suggestions to improve code quality, maintainability, and correctness.

🎯 Overall Assessment

The functionality works as intended, but there are several areas for improvement:

🔧 Issues & Recommendations

1. Constants Discrepancy

There's a mismatch between the constant and documentation:

  • internal/tuple/import.go: MaxParallelRequests = 10
  • Documentation states default is 4
  • The flag initialization uses tuple.MaxParallelRequests (which is 10)

Recommendation: Clarify which value is correct and update accordingly.

2. Magic Numbers Should Be Constants

The conditional logic uses hardcoded values:

// Current implementation
maxTuplesPerWrite = 40
defaultParallel := maxRPS / 5
rampUpPeriodInSec = maxRPS * 2

Recommendation: Extract these to named constants:

const (
    DefaultMaxTuplesPerWriteWithRPS = 40
    RPSToParallelRequestsDivisor = 5
    RPSToRampupPeriodMultiplier = 2
)

3. Extract Conditional Logic to Testable Function

The flag defaulting logic is embedded in the main function, making it hard to test.

Recommendation: Extract to a separate function:

type FlagDefaults struct {
    MaxTuplesPerWrite   int
    MaxParallelRequests int
    RampupPeriodInSec   int
}

func calculateDynamicDefaults(maxRPS int, flags *flag.FlagSet) FlagDefaults {
    defaults := FlagDefaults{}
    
    if maxRPS > 0 {
        if !flags.Changed("max-tuples-per-write") {
            defaults.MaxTuplesPerWrite = DefaultMaxTuplesPerWriteWithRPS
        }
        
        if !flags.Changed("max-parallel-requests") {
            parallelRequests := maxRPS / RPSToParallelRequestsDivisor
            if parallelRequests < 1 {
                parallelRequests = 1
            }
            defaults.MaxParallelRequests = parallelRequests
        }
        
        if !flags.Changed("rampup-period-in-sec") {
            defaults.RampupPeriodInSec = maxRPS * RPSToRampupPeriodMultiplier
        }
    }
    
    return defaults
}

4. Add Validation for Edge Cases

Consider edge cases:

  • What if maxRPS is 1-4? The division by 5 results in 0, but you set minimum to 1.
  • Should there be upper limits on calculated values?

Recommendation: Add validation and consider warning users:

if maxRPS > 0 && maxRPS < RPSToParallelRequestsDivisor {
    // Maybe log a warning about low RPS values
}

5. Missing Tests

There are no tests for the new conditional logic.

Recommendation: Add comprehensive tests:

func TestCalculateDynamicDefaults(t *testing.T) {
    tests := []struct {
        name     string
        maxRPS   int
        setFlags map[string]bool
        expected FlagDefaults
    }{
        {
            name:   "maxRPS 10 with no flags set",
            maxRPS: 10,
            expected: FlagDefaults{
                MaxTuplesPerWrite:   40,
                MaxParallelRequests: 2,
                RampupPeriodInSec:   20,
            },
        },
        {
            name:   "maxRPS 1 (edge case)",
            maxRPS: 1,
            expected: FlagDefaults{
                MaxTuplesPerWrite:   40,
                MaxParallelRequests: 1, // minimum enforced
                RampupPeriodInSec:   2,
            },
        },
        // Add more test cases...
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            // Test implementation
        })
    }
}

6. Documentation Clarity

The README is good but could be clearer about the conditional behavior.

Recommendation: Consider adding a dedicated section explaining the dynamic defaults:

##### Dynamic Defaults with --max-rps

When `--max-rps` is specified, the following flags will have dynamic defaults if not explicitly set:

| Flag | Default When --max-rps is Set | Regular Default |
|------|------------------------------|-----------------|
| `--max-tuples-per-write` | 40 | 1 |
| `--max-parallel-requests` | max-rps/5 (min: 1) | 4 |
| `--rampup-period-in-sec` | max-rps*2 | N/A |

7. Consider Validation Order

The current validation happens after the conditional defaults are set. Consider if this order is optimal.

🚀 Suggested Refactoring

Here's how I'd structure the improved version:

func writeTuplesFromFile(ctx context.Context, flags *flag.FlagSet, fgaClient *client.OpenFgaClient) error {
    // Parse and validate individual flags first
    params, err := parseTupleWriteFlags(flags)
    if err != nil {
        return err
    }
    
    // Apply dynamic defaults if needed
    params = applyDynamicDefaults(params, flags)
    
    // Validate final parameters
    if err := validateTupleWriteParams(params); err != nil {
        return err
    }
    
    // Continue with actual tuple writing logic...
}

What's Working Well

  1. Good user experience - automatic optimization based on RPS settings
  2. Backward compatibility - existing behavior unchanged when flags are explicitly set
  3. Documentation updates - comprehensive README updates
  4. Removed coupling - no longer requiring rampup-period-in-sec with max-rps

This is a solid feature that will improve user experience significantly! The suggestions above will make it more maintainable and robust.

@aaguiarz
Copy link
Member Author

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Jun 15, 2025

✅ 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
Contributor

@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

🧹 Nitpick comments (1)
README.md (1)

674-679: Use consistent list markers and punctuation in parameter bullets

Switch unordered list markers to dashes for consistency (MD004) and add a comma after “omitted” in the --max-rps description for clarity.

- * `--max-tuples-per-write`: Max tuples to send in a single write (optional, default=1, or 40 if `--max-rps` is set and this flag is omitted)
+ - `--max-tuples-per-write`: Max tuples to send in a single write (optional, default=1, or 40 if `--max-rps` is set and this flag is omitted)

- * `--max-parallel-requests`: Max requests to send in parallel (optional, default=4, or `max-rps/5` if `--max-rps` is set and this flag is omitted)
+ - `--max-parallel-requests`: Max requests to send in parallel (optional, default=4, or `max-rps/5` if `--max-rps` is set and this flag is omitted)

- * `--max-rps`: Max requests per second. When set, the CLI will ramp up requests from 1 RPS to the set value. If `--rampup-period-in-sec` is omitted it defaults to `max-rps*2`.
+ - `--max-rps`: Max requests per second. When set, the CLI will ramp up requests from 1 RPS to the set value. If `--rampup-period-in-sec` is omitted, it defaults to `max-rps*2`.

- * `--rampup-period-in-sec`: Time in seconds to wait between each batch of tuples when ramping up. Only used if `--max-rps` is set.
+ - `--rampup-period-in-sec`: Time in seconds to wait between each batch of tuples when ramping up. Only used if `--max-rps` is set.

- * All integer parameters must be greater than zero when provided.
+ - All integer parameters must be greater than zero when provided.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~677-~677: Possible missing comma found.
Context: ...t value. If --rampup-period-in-sec is omitted it defaults to max-rps*2. * `--rampup...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~678-~678: Loose punctuation mark.
Context: ... max-rps*2. * --rampup-period-in-sec: Time in seconds to wait between each ba...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)

674-674: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


675-675: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


676-676: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


677-677: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


678-678: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


679-679: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b1d24e and cf697d9.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • cmd/tuple/write.go (4 hunks)
  • internal/tuple/import.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • internal/tuple/import.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/tuple/write.go
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~677-~677: Possible missing comma found.
Context: ...t value. If --rampup-period-in-sec is omitted it defaults to max-rps*2. * `--rampup...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~678-~678: Loose punctuation mark.
Context: ... max-rps*2. * --rampup-period-in-sec: Time in seconds to wait between each ba...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 markdownlint-cli2 (0.17.2)
README.md

674-674: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


675-675: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


676-676: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


677-677: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


678-678: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)


679-679: Unordered list style
Expected: dash; Actual: asterisk

(MD004, ul-style)

🔇 Additional comments (1)
README.md (1)

685-685: Approve simplification of example usage

The updated example succinctly demonstrates the dynamic defaults when only --max-rps is specified, improving user clarity.

@aaguiarz aaguiarz requested a review from rhamzeh June 17, 2025 18:21
@aaguiarz aaguiarz marked this pull request as ready for review June 17, 2025 18:21
@dyeam0 dyeam0 requested a review from Siddhant-K-code June 24, 2025 04:41
Copy link
Member

@Siddhant-K-code Siddhant-K-code left a comment

Choose a reason for hiding this comment

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

Overall looks good % nit comment

@rhamzeh rhamzeh changed the title Add dynamic defaults for tuple write command feat: add dynamic defaults for tuple write command Jun 26, 2025
@rhamzeh rhamzeh added this pull request to the merge queue Jun 26, 2025
Merged via the queue into main with commit 9f75e47 Jun 26, 2025
22 checks passed
@rhamzeh rhamzeh deleted the codex/change-default-values-for-write-command branch June 26, 2025 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants