Skip to content

chore: clean up after changing ratelimit implementation#3081

Merged
chronark merged 4 commits intomainfrom
clean-ratelimits
Apr 8, 2025
Merged

chore: clean up after changing ratelimit implementation#3081
chronark merged 4 commits intomainfrom
clean-ratelimits

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Apr 7, 2025

Summary by CodeRabbit

  • New Features

    • Added enhanced API configuration options including container image selection, test mode, unique instance IDs, and support for Prometheus metrics.
    • Introduced new CLI flags for HTTP port (default 7070), colored logging, database connections, and a direct Redis URL.
  • Improvements

    • Streamlined deployment by removing clustering configurations in favor of a simplified, direct Redis connection.
    • Enhanced observability and logging for clearer operational insights.
    • Updated MySQL container configuration options for reuse and purging behavior.
  • Documentation

    • Updated guides on API architecture and rate limiting for improved clarity and production-readiness.

@vercel
Copy link

vercel bot commented Apr 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 7, 2025 4:22pm
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 7, 2025 4:22pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 7, 2025 4:22pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Apr 7, 2025 4:22pm

@changeset-bot
Copy link

changeset-bot bot commented Apr 7, 2025

⚠️ No Changeset found

Latest commit: f99828a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 7, 2025

📝 Walkthrough

Walkthrough

This pull request encompasses widespread refactoring and configuration updates across the project. The changes affect GitHub Actions workflows, API route tests, configuration documentation, CLI flag definitions, Docker deployments, build and test tasks, and integration tests for rate limiting. In addition, there is a major migration from OpenTelemetry to Prometheus for metrics collection, removal of legacy clustering, discovery, membership, and ring implementations, as well as updates to dependency versions and test container handling. Overall, the PR streamlines testing, observability, and distributed system configurations.

Changes

File(s) Change Summary
.github/workflows/job_test_go_api_local.yaml Updated test command to use the -shuffle=on flag, replacing the previous -v -race flags while retaining timeout and shard test settings.
apps/api/src/routes/v1_ratelimits_limit.ts, go/apps/api/routes/v2_ratelimit*_test.go Modified API route tests to parse nested JSON (data.success) and generate dynamic namespace IDs using uid.New("test"); replaced util.Pointer with ptr.P in request bodies.
go/apps/api/config.go, go/cmd/api/main.go Removed the LogsColor field; restructured CLI flags to introduce new options (e.g., http-port, color, test-mode, database-primary, redis-url) and removed clustering-related flags.
apps/engineering/.../config.mdx, apps/engineering/.../ratelimiting.mdx, deployment/docker-compose.yaml Revised API configuration documentation and deployment scripts by adding new properties (such as image, test-mode, instance-id, prometheus-port) and observability settings while eliminating clustering options.
go/Taskfile.yml Introduced a new build-docker task; updated test tasks to run full tests with JSON output, parallel execution, a specific timeout, and shuffling; modified unit tests to skip integration tests.
go/apps/api/integration/multi_node_ratelimiting/* Removed the accuracy integration test; added a test case generator and a new RunRateLimitTest function for multi-node rate limiting; disabled OpenTelemetry initialization in the harness.
go/pkg/cache/*, go/pkg/ratelimiting/*, go/pkg/zen/middleware_metrics.go, go/pkg/prometheus/metrics/* Transitioned metrics collection from OpenTelemetry to Prometheus by simplifying metric calls (using Inc, Observe, Set) and updating log levels from debug to info.
go/pkg/otel/metrics/* Removed legacy OpenTelemetry metrics implementation files in favor of Prometheus-based metrics instrumentation.
go/pkg/cluster/*, go/pkg/discovery/*, go/pkg/membership/*, go/pkg/ring/* Removed deprecated clustering, discovery, membership, and consistent hashing implementations to streamline distributed functionality.
go/go.mod Cleaned up dependencies by removing unused packages (e.g., AWS SDK v2, HashiCorp libraries, connect-related packages) and updating versions of remaining dependencies for improved stability.
go/pkg/testutil/containers/mysql.go, go/pkg/testutil/http.go, go/pkg/testutil/seed/seed.go, go/pkg/uid/uid_test.go Enhanced test container configuration with new reuse/purge options, improved duplicate entry error handling in seeding, and updated UID generation by adjusting import paths and prefix usage.
go/pkg/zen/server.go Removed the InstanceID field from the server configuration to simplify instance identification.
go/proto/ratelimit/v1/service.proto Deleted protocol buffer definitions for the rate limiting service (messages and service RPC) to phase out outdated RPC-based synchronization mechanisms.

Sequence Diagram(s)

sequenceDiagram
    participant T as Test Function
    participant H as Integration Harness
    participant R as RunRateLimitTest
    participant M as Metrics Validator

    T->>H: Initialize test harness
    H->>R: Invoke RunRateLimitTest(limit, duration, windowCount, loadFactor, nodeCount)
    R->>H: Setup rate limit namespace & generate root key
    R->>H: Calculate RPS and dispatch requests via load balancer
    H->>M: Collect and log metrics
    M->>R: Return success metrics
    R->>T: Report test outcome
Loading
sequenceDiagram
    participant C as Client Request
    participant M as Middleware (Prometheus)
    participant P as Prometheus Collector

    C->>M: Submit HTTP Request
    M->>P: Increment HTTPRequestTotal counter & observe latency with HTTPRequestLatency
    M->>C: Return HTTP Response
Loading

Possibly related PRs

  • test: containierzed integration tests #2996: Modifications in the GitHub Actions workflow for testing a Go API are related. Both PRs adjust test execution commands, with this one replacing flags and the other implementing a concurrent matrix strategy.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


🪧 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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@github-actions
Copy link
Contributor

github-actions bot commented Apr 7, 2025

Thank you for following the naming conventions for pull request titles! 🙏

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

🧹 Nitpick comments (12)
go/apps/api/routes/v2_ratelimit_set_override/403_test.go (1)

24-24: Inconsistent prefix compared to other files

While using uid.New() is a good improvement, this file uses the prefix "name" while other similar test files use "test". Consider standardizing the prefix across all files for better consistency.

-	namespaceName := uid.New("name")
+	namespaceName := uid.New("test")
apps/engineering/content/architecture/services/api/ratelimiting.mdx (2)

15-15: Consider adding hyphens to compound adjectives

For improved readability, consider adding hyphens to compound adjectives:

  • "rate-limiting system" instead of "rate limiting system" (line 15)
  • "decision-making" instead of "decision making" (lines 33 and 83)

This follows standard English grammar rules for compound adjectives that precede nouns.

Also applies to: 33-33, 83-83

🧰 Tools
🪛 LanguageTool

[uncategorized] ~15-~15: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ents ### Sliding Window Algorithm The rate limiting system uses a sliding window algorithm ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


57-57: Missing period at end of sentence

There appears to be a missing period at the end of the sentence: "This ensures eventual consistency without adding latency to API responses"

🧰 Tools
🪛 LanguageTool

[uncategorized] ~57-~57: A period might be missing here.
Context: ...nsistency without adding latency to API responses ### 3. Redis Synchronization The syst...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)

apps/engineering/content/architecture/services/api/config.mdx (1)

232-233: Consider adding a comma

Consider adding a comma after "debugging" in the sentence: "This is useful for local development and debugging, but may need to be disabled in production environments..."

🧰 Tools
🪛 LanguageTool

[uncategorized] ~233-~233: Possible missing comma found.
Context: ...eful for local development and debugging but may need to be disabled in production e...

(AI_HYDRA_LEO_MISSING_COMMA)

.github/workflows/job_test_go_api_local.yaml (1)

22-24: Improved test randomization with shuffle mode

Replaced -v -race flags with -shuffle=on in the test command. This change improves test reliability by randomizing the order of test execution, which helps identify tests that incorrectly depend on execution order.

However, consider if removing the -race flag was intentional, as it's useful for detecting race conditions.

-        run: go test -shuffle=on -timeout=60m $(go run ./scripts/shard-test ${{ matrix.shard }})
+        run: go test -shuffle=on -race -timeout=60m $(go run ./scripts/shard-test ${{ matrix.shard }})
go/apps/api/integration/harness.go (1)

43-43: Commented out OpenTelemetry for testing

The OpenTelemetry container initialization has been commented out, aligning with the PR's objective of cleaning up after changing the ratelimit implementation. This suggests a shift away from using OpenTelemetry for metrics in the testing environment.

Consider adding a comment explaining why OpenTelemetry is no longer needed or replacing the comment with code removal if it's permanently deprecated.

-	//containerMgr.RunOtel(true)
+	// OpenTelemetry no longer used for metrics after ratelimit implementation change
go/apps/api/integration/multi_node_ratelimiting/generate_tests/main.go (3)

23-31: Consider validating package name generation
If any parameter has invalid characters, the generated package name might break the build.


47-52: Be mindful of test expansions
As you add more test parameters, the file generation might become exceptionally large. Evaluate if there's any risk of generating too many tests.


86-94: Avoid panicking on file/directory errors
Panicking is acceptable in convenience scripts, but consider graceful error handling or logging in a production context.

go/pkg/cache/cache.go (1)

107-110: Avoid overwriting old metric data
While using Set(...) is valid for current stats, verify that periodically setting these values does not introduce concurrency conflicts or unexpected results.

go/apps/api/integration/multi_node_ratelimiting/run.go (2)

36-44: Add transaction or additional error checks
Consider wrapping namespace creation in a transaction or checking for collisions in repeated test runs.


147-164: Validate distribution among nodes
You check that each node receives traffic. For thoroughness, consider capturing per-node success counts to ensure balanced load distribution.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e6e4dd6 and adcce03.

⛔ Files ignored due to path filters (217)
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit1000_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit100_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes1_limit5_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit1000_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit100_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes3_limit5_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit1000_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit100_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration1000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration3600000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration60000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load0_90_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load0_90_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load10_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load10_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load2_00_windows10/generated_test.go is excluded by !**/generated/**
  • go/apps/api/integration/multi_node_ratelimiting/generated/ratelimit_nodes9_limit5_duration86400000_load2_00_windows100/generated_test.go is excluded by !**/generated/**
  • go/go.sum is excluded by !**/*.sum
📒 Files selected for processing (82)
  • .github/workflows/job_test_go_api_local.yaml (1 hunks)
  • apps/api/src/routes/v1_ratelimits_limit.ts (2 hunks)
  • apps/engineering/content/architecture/services/api/config.mdx (4 hunks)
  • apps/engineering/content/architecture/services/api/ratelimiting.mdx (1 hunks)
  • deployment/docker-compose.yaml (1 hunks)
  • go/Taskfile.yml (2 hunks)
  • go/apps/api/cancel_test.go (0 hunks)
  • go/apps/api/config.go (0 hunks)
  • go/apps/api/integration/harness.go (1 hunks)
  • go/apps/api/integration/multi_node_ratelimiting/accuracy_test.go (0 hunks)
  • go/apps/api/integration/multi_node_ratelimiting/generate_tests/main.go (1 hunks)
  • go/apps/api/integration/multi_node_ratelimiting/run.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/200_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/400_test.go (5 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/401_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/403_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/404_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/200_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/400_test.go (5 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/401_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/403_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/404_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/200_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/400_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/403_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/404_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/200_test.go (3 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/400_test.go (7 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/401_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/403_test.go (1 hunks)
  • go/apps/api/run.go (1 hunks)
  • go/cmd/api/main.go (1 hunks)
  • go/go.mod (7 hunks)
  • go/internal/services/ratelimit/bucket.go (2 hunks)
  • go/internal/services/ratelimit/janitor.go (2 hunks)
  • go/internal/services/ratelimit/replay.go (2 hunks)
  • go/internal/services/ratelimit/window.go (2 hunks)
  • go/pkg/cache/cache.go (5 hunks)
  • go/pkg/circuitbreaker/lib_test.go (1 hunks)
  • go/pkg/cluster/cluster.go (0 hunks)
  • go/pkg/cluster/cluster_test.go (0 hunks)
  • go/pkg/cluster/doc.go (0 hunks)
  • go/pkg/cluster/interface.go (0 hunks)
  • go/pkg/cluster/noop.go (0 hunks)
  • go/pkg/counter/doc.go (1 hunks)
  • go/pkg/counter/redis_test.go (0 hunks)
  • go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go (1 hunks)
  • go/pkg/db/querier_generated.go (1 hunks)
  • go/pkg/db/queries/permission_find_by_workspace_and_name.sql (1 hunks)
  • go/pkg/discovery/awsecs.go (0 hunks)
  • go/pkg/discovery/doc.go (0 hunks)
  • go/pkg/discovery/interface.go (0 hunks)
  • go/pkg/discovery/redis.go (0 hunks)
  • go/pkg/discovery/static.go (0 hunks)
  • go/pkg/membership/doc.go (0 hunks)
  • go/pkg/membership/interface.go (0 hunks)
  • go/pkg/membership/logger.go (0 hunks)
  • go/pkg/membership/member.go (0 hunks)
  • go/pkg/membership/membership_test.go (0 hunks)
  • go/pkg/membership/serf.go (0 hunks)
  • go/pkg/otel/grafana.go (0 hunks)
  • go/pkg/otel/metrics/doc.go (0 hunks)
  • go/pkg/otel/metrics/interface.go (0 hunks)
  • go/pkg/otel/metrics/metrics.go (0 hunks)
  • go/pkg/otel/metrics/observable.go (0 hunks)
  • go/pkg/prometheus/metrics/cache.go (1 hunks)
  • go/pkg/prometheus/metrics/http.go (1 hunks)
  • go/pkg/prometheus/metrics/ratelimit.go (1 hunks)
  • go/pkg/prometheus/promhttp.go (0 hunks)
  • go/pkg/prometheus/server.go (1 hunks)
  • go/pkg/ring/consistency/checker.go (0 hunks)
  • go/pkg/ring/doc.go (0 hunks)
  • go/pkg/ring/ring.go (0 hunks)
  • go/pkg/ring/ring_test.go (0 hunks)
  • go/pkg/testutil/containers/mysql.go (3 hunks)
  • go/pkg/testutil/http.go (2 hunks)
  • go/pkg/testutil/seed/seed.go (2 hunks)
  • go/pkg/uid/uid_test.go (2 hunks)
  • go/pkg/zen/middleware_logger.go (1 hunks)
  • go/pkg/zen/middleware_metrics.go (2 hunks)
  • go/pkg/zen/server.go (0 hunks)
  • go/proto/ratelimit/v1/service.proto (0 hunks)
💤 Files with no reviewable changes (32)
  • go/pkg/membership/doc.go
  • go/apps/api/cancel_test.go
  • go/apps/api/config.go
  • go/pkg/ring/ring_test.go
  • go/pkg/membership/logger.go
  • go/pkg/counter/redis_test.go
  • go/pkg/cluster/cluster_test.go
  • go/pkg/cluster/doc.go
  • go/pkg/discovery/doc.go
  • go/pkg/discovery/static.go
  • go/pkg/ring/doc.go
  • go/pkg/discovery/interface.go
  • go/pkg/otel/metrics/interface.go
  • go/pkg/ring/consistency/checker.go
  • go/pkg/cluster/interface.go
  • go/pkg/otel/metrics/metrics.go
  • go/pkg/membership/membership_test.go
  • go/pkg/otel/metrics/doc.go
  • go/pkg/prometheus/promhttp.go
  • go/pkg/zen/server.go
  • go/pkg/cluster/noop.go
  • go/pkg/otel/grafana.go
  • go/pkg/ring/ring.go
  • go/pkg/membership/interface.go
  • go/apps/api/integration/multi_node_ratelimiting/accuracy_test.go
  • go/pkg/otel/metrics/observable.go
  • go/pkg/discovery/redis.go
  • go/pkg/membership/member.go
  • go/pkg/membership/serf.go
  • go/proto/ratelimit/v1/service.proto
  • go/pkg/discovery/awsecs.go
  • go/pkg/cluster/cluster.go
🧰 Additional context used
🧬 Code Definitions (21)
go/apps/api/routes/v2_ratelimit_get_override/401_test.go (1)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_get_override/403_test.go (4)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_delete_override/401_test.go (1)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_set_override/403_test.go (5)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_limit/404_test.go (4)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_limit/403_test.go (5)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_set_override/401_test.go (2)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/testutil/http.go (2)
go/pkg/testutil/containers/mysql.go (2)
  • WithReuse (23-27)
  • WithPurge (29-33)
apps/agent/pkg/logging/logger.go (1)
  • Logger (13-13)
go/apps/api/routes/v2_ratelimit_delete_override/200_test.go (2)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_limit/200_test.go (1)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_limit/400_test.go (1)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_set_override/400_test.go (2)
go/pkg/ptr/pointer.go (1)
  • P (49-51)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/apps/api/routes/v2_ratelimit_delete_override/404_test.go (3)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_get_override/404_test.go (4)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/apps/api/integration/harness.go (1)
  • New (35-70)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_set_override/200_test.go (2)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
  • New (31-123)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/apps/api/run.go (1)
go/pkg/otel/logging/interface.go (1)
  • Logger (11-116)
go/pkg/uid/uid_test.go (1)
go/pkg/uid/uid.go (2)
  • APIPrefix (20-20)
  • New (63-83)
go/apps/api/routes/v2_ratelimit_delete_override/400_test.go (1)
go/pkg/ptr/pointer.go (1)
  • P (49-51)
go/pkg/testutil/containers/mysql.go (1)
go/pkg/testutil/containers/containers.go (1)
  • Containers (13-17)
go/apps/api/routes/v2_ratelimit_get_override/400_test.go (1)
go/pkg/ptr/pointer.go (1)
  • P (49-51)
go/cmd/api/main.go (5)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
  • New (42-229)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
  • New (33-216)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)
  • New (29-124)
go/pkg/clickhouse/client.go (1)
  • New (59-161)
go/pkg/uid/uid.go (1)
  • InstancePrefix (34-34)
🪛 LanguageTool
apps/engineering/content/architecture/services/api/ratelimiting.mdx

[uncategorized] ~9-~9: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... The Unkey API implements a distributed rate limiting system using a sliding window algorithm...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~15-~15: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ents ### Sliding Window Algorithm The rate limiting system uses a sliding window algorithm ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~33-~33: The noun “decision-making” (= the process of deciding something) is spelled with a hyphen.
Context: ...aintains local in-memory state for fast decision making: 1. Buckets: Track rate limit stat...

(DECISION_MAKING)


[uncategorized] ~57-~57: A period might be missing here.
Context: ...nsistency without adding latency to API responses ### 3. Redis Synchronization The syst...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)


[uncategorized] ~83-~83: The noun “Decision-Making” (= the process of deciding something) is spelled with a hyphen.
Context: ...## Performance Optimizations - Local Decision Making: Most decisions made locally avoid Re...

(DECISION_MAKING)

apps/engineering/content/architecture/services/api/config.mdx

[uncategorized] ~233-~233: Possible missing comma found.
Context: ...eful for local development and debugging but may need to be disabled in production e...

(AI_HYDRA_LEO_MISSING_COMMA)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Go API Local / Test (Shard 1/8)
  • GitHub Check: Test Go API Local / Test (Shard 5/8)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Go API Local / Test (Shard 2/8)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
🔇 Additional comments (111)
go/apps/api/routes/v2_ratelimit_delete_override/401_test.go (2)

10-10: Import added for uid package

The uid package is now imported to support the dynamic generation of test identifiers.


31-31: Improved test robustness by using dynamic identifiers

Replacing the static string "test_namespace" with a dynamically generated identifier using uid.New("test") helps prevent potential test interference when tests run in parallel and better simulates real-world usage where IDs would be unique.

go/apps/api/routes/v2_ratelimit_get_override/403_test.go (1)

24-24: Enhanced test isolation with dynamic namespace identifier

Replacing the hardcoded namespace name with a dynamically generated identifier using uid.New("test") improves test isolation and prevents potential conflicts between test runs.

go/apps/api/routes/v2_ratelimit_get_override/401_test.go (2)

10-10: Import added for uid package

The uid package is now properly imported to support the dynamic generation of test identifiers.


31-31: Improved test reliability with dynamic identifiers

Switching from static string "test_namespace" to a dynamically generated identifier using uid.New("test") helps prevent test interference and better represents real-world conditions.

go/apps/api/routes/v2_ratelimit_limit/404_test.go (1)

62-62: Enhanced test isolation with dynamic namespace identifier

Using uid.New("test") for the deleted namespace name rather than a static string improves test isolation by ensuring unique identifiers for each test run, preventing potential conflicts from leftover data.

go/apps/api/routes/v2_ratelimit_limit/400_test.go (1)

36-36: Good improvement using dynamic namespace IDs

The change from hardcoded "test_namespace" to using uid.New("test") improves test reliability by generating unique identifiers for each test run. This prevents potential test interference and aligns with modern testing practices.

go/apps/api/routes/v2_ratelimit_limit/403_test.go (1)

24-24: Good improvement using dynamic namespace IDs

Using uid.New("test") instead of a hardcoded string ensures test isolation by generating unique namespace identifiers for each test run, preventing potential interference between tests.

go/apps/api/routes/v2_ratelimit_get_override/200_test.go (1)

23-23: Good improvement using dynamic namespace IDs

The change from hardcoded "test_namespace" to using uid.New("test") improves test isolation and reliability by generating unique identifiers for each test run.

go/apps/api/routes/v2_ratelimit_delete_override/200_test.go (1)

23-23: Improved test reliability with dynamic namespace naming

Using uid.New("test") instead of a hardcoded string enhances test reliability by ensuring each test run uses a unique namespace name. This prevents potential conflicts when tests run in parallel or when test data persists between runs.

go/apps/api/routes/v2_ratelimit_delete_override/404_test.go (1)

24-24: LGTM: Consistent use of unique identifiers

This change follows the same pattern as in other test files, replacing hardcoded namespace names with dynamically generated ones for better test isolation.

go/apps/api/routes/v2_ratelimit_limit/200_test.go (1)

23-23: Consistent improvement to test robustness

The change from hardcoded namespace name to a dynamically generated one follows the same pattern seen in other test files, ensuring test isolation and preventing potential data conflicts.

go/apps/api/routes/v2_ratelimit_get_override/404_test.go (2)

24-24: LGTM: Consistent improvement to test stability

Using uid.New("test") follows the same pattern as other test changes, ensuring unique namespace names for test isolation.


41-41: More precise permission scoping in root key creation

Changed from using a wildcard permission to a namespace-specific permission. This makes the test more realistic, as it now reflects how permissions would typically be scoped in production environments.

go/apps/api/routes/v2_ratelimit_delete_override/403_test.go (1)

24-24: Good improvement to use dynamic namespace naming

Changing from a static string to uid.New("test") improves test isolation by ensuring unique namespace names across test runs, which helps prevent potential test interference when running tests concurrently.

go/apps/api/routes/v2_ratelimit_set_override/401_test.go (2)

10-10: LGTM: Import required for uid.New

Properly added the uid package import to support the dynamic namespace name generation.


31-31: Consistent approach to namespace name generation

Using uid.New("test") instead of a static string aligns with other test files and ensures test isolation with unique namespace names.

go/apps/api/routes/v2_ratelimit_get_override/400_test.go (5)

12-14: Good package update for pointer handling and unique ID generation

Updating the imports to use ptr package for pointer creation and adding the uid package for unique ID generation improves code consistency across the codebase.


54-54: Updated pointer creation to use consistent package

Changed from using util.Pointer to ptr.P for pointer creation, which is more concise and follows the project's standardized approach.


73-74: Consistent pointer creation pattern

Updated pointer creation to use ptr.P for consistency with the rest of the codebase.


119-119: Dynamic namespace name generation for better test isolation

Using uid.New("test") instead of a static string prevents potential test collisions when running tests concurrently.


136-136: Consistent namespace name generation

Using uid.New("test") maintains consistency with other test cases and improves test isolation.

go/pkg/uid/uid_test.go (3)

7-7: Updated import path reflecting package reorganization

Updated the import path from apps/agent/pkg/uid to go/pkg/uid, aligning with the project's restructuring.


23-23: Updated test to use APIPrefix instead of NodePrefix

Changed the test to use uid.APIPrefix instead of uid.NodePrefix, which aligns with the current API structure.


29-29: Simplified function call by removing unnecessary type conversion

Removed the explicit string() conversion when calling uid.New(), as the function now directly accepts the Prefix type.

go/apps/api/routes/v2_ratelimit_delete_override/400_test.go (5)

11-13: Improved imports with specialized packages

The imports now use the dedicated ptr and uid packages, which provide more specialized functionality than generic utility functions. The ptr package offers type-safe pointer creation, and uid generates unique identifiers with proper formatting.


53-53: Clean pointer creation with generic helper

Replaced utility pointer creation with ptr.P which provides a cleaner, more type-safe way to create pointers to values. This approach is more maintainable and consistent with Go's idiomatic practices.


72-72: Consistent pointer creation pattern

Consistently applying ptr.P for pointer creation throughout the codebase improves readability and maintainability.


117-117: Enhanced test data with unique identifiers

Using uid.New("test") instead of hardcoded values improves test isolation by ensuring each test run has unique identifiers, which helps prevent potential test interference and makes debugging easier.


134-134: Consistent use of unique identifiers

Consistently using uid.New() across test cases ensures a uniform approach to test data generation.

go/apps/api/routes/v2_ratelimit_set_override/400_test.go (3)

11-13: Improved imports with specialized packages

The imports now use the dedicated ptr and uid packages, which provide more specialized functionality than generic utility functions. This makes the code more maintainable and follows the principle of using the most specific tool for the job.


53-53: Consistent use of ptr.P across all test cases

The change uniformly applies ptr.P for pointer creation throughout all test cases, improving code consistency. The generic function P[T any](t T) *T provides a cleaner, more type-safe way to create pointers compared to the previous approach.

Also applies to: 74-74, 97-97, 118-118, 140-140


189-189: Enhanced test data with unique identifiers

Using uid.New("test") instead of hardcoded namespace names improves test isolation and prevents potential test interference by ensuring each test run has unique identifiers. This is particularly important for tests that may run in parallel or be executed multiple times.

go/apps/api/routes/v2_ratelimit_set_override/200_test.go (3)

23-23: Enhanced test data with unique identifiers

Using uid.New("test") instead of a hardcoded namespace name improves test isolation and makes tests more robust by ensuring each test run has unique identifiers.


41-41: Improved permission specification

The permission string now uses the namespace ID directly through fmt.Sprintf("ratelimit.%s.set_override", namespaceID), which makes the permission scoping more explicit and correctly tied to the specific resource being tested. This makes the test more accurate in representing real-world permission scenarios.


58-58: Enhanced error reporting

Changed error message format from %v to %+v, which provides more detailed output when tests fail. This makes debugging failed tests easier by showing the full struct content including field names.

go/pkg/counter/doc.go (1)

43-44: The package declaration is correctly formatted.

The code appears to be a proper package declaration with no issues.

go/pkg/zen/middleware_logger.go (1)

27-32: Adjusted logging level from Debug to Info.

This change increases the visibility of request logs by moving them from debug level to info level. This is useful for operational monitoring and ensures that standard request information is readily available in production logs without enabling debug mode.

go/pkg/circuitbreaker/lib_test.go (1)

10-10: Updated import path for the clock package.

The import has been correctly updated to reflect the new location of the clock package in the project structure, aligning with broader codebase reorganization efforts mentioned in the PR objectives.

apps/api/src/routes/v1_ratelimits_limit.ts (2)

412-412: Updated response type to match new AWS API structure.

The code correctly adapts to the API response structure change, where the success boolean is now nested inside a data object.


422-423: Updated property access to match new response structure.

This change ensures proper access to the success field within the nested data object structure returned by the AWS API.

go/pkg/prometheus/server.go (4)

1-15: Well-structured package documentation

The documentation provides a clear overview of the package's purpose and common use cases. The comprehensive explanation helps developers understand when and how to use this package, which is essential for proper integration.


26-32: Clear and concise config structure

The Config struct is well-documented with appropriate comments explaining the purpose of each field. The simple design with just a Logger dependency makes it easy to use and maintain.


34-73: Excellent function documentation with examples

The documentation for the New function is very comprehensive, including parameters, return values, an explanation of what the function does, and a practical usage example. This level of detail helps developers understand how to use the function correctly.


74-92: Simple and effective implementation

The implementation is clean and follows good practices. It leverages the zen server framework consistently while providing a focused functionality for exposing Prometheus metrics.

go/internal/services/ratelimit/window.go (2)

3-7: Properly migrated from OpenTelemetry to Prometheus metrics

The import has been updated to use the Prometheus metrics package instead of OpenTelemetry, aligning with the broader migration strategy indicated in the PR summary.


57-58: Simplified metrics collection

The metrics tracking has been updated from metrics.Ratelimit.CreatedWindows.Add(context.Background(), 1) to the more straightforward metrics.RatelimitWindowsCreated.Inc(), which simplifies the code and removes the unnecessary context parameter.

apps/engineering/content/architecture/services/api/ratelimiting.mdx (7)

7-9: Improved architecture overview section

The new "Overview" section provides a clearer, more concise introduction to the rate limiting system than the previous "Cluster Formation" section. It effectively communicates the key aspects of the architecture.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~9-~9: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... The Unkey API implements a distributed rate limiting system using a sliding window algorithm...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


13-22: Well-structured explanation of sliding window algorithm

The explanation of the sliding window algorithm is clear and detailed, breaking down complex concepts into digestible points. This helps developers understand how the rate limiting system works at a fundamental level.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~15-~15: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ents ### Sliding Window Algorithm The rate limiting system uses a sliding window algorithm ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


23-30: Clear explanation of Redis's role in the architecture

The document effectively explains how Redis serves as the centralized counter store for rate limiting, detailing its role in maintaining atomic counters, managing TTL, and ensuring consistent counting across nodes.


31-38: Good description of local in-memory state

The section on local in-memory state clearly explains how each API node maintains local state for fast decision making, including the concepts of buckets, windows, and memory management.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~33-~33: The noun “decision-making” (= the process of deciding something) is spelled with a hyphen.
Context: ...aintains local in-memory state for fast decision making: 1. Buckets: Track rate limit stat...

(DECISION_MAKING)


41-66: Comprehensive request flow documentation

The request flow section provides a detailed step-by-step explanation of how rate limit requests are processed, including initial checks, asynchronous synchronization, and Redis synchronization. This helps developers understand the complete lifecycle of a request.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~57-~57: A period might be missing here.
Context: ...nsistency without adding latency to API responses ### 3. Redis Synchronization The syst...

(AI_EN_LECTOR_MISSING_PUNCTUATION_PERIOD)


69-87: Thorough implementation details

The implementation details sections (Bucket and Window Management, Resilience Features, Performance Optimizations) provide valuable insights into how the system works internally and handles edge cases. This information is crucial for maintainers and contributors.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~83-~83: The noun “Decision-Making” (= the process of deciding something) is spelled with a hyphen.
Context: ...## Performance Optimizations - Local Decision Making: Most decisions made locally avoid Re...

(DECISION_MAKING)


88-106: Comprehensive deployment considerations

The deployment considerations section provides valuable information about Redis configuration, scaling strategies, and the overall architecture's balance between accuracy, performance, and operational simplicity. This helps operators understand how to effectively deploy and scale the system.

apps/engineering/content/architecture/services/api/config.mdx (8)

84-92: Well-documented new --image property

The new --image property is well-documented with clear examples and environment variable mapping. This will help users correctly specify the container image for deployment.


101-109: Important security warning in --test-mode documentation

The documentation for --test-mode appropriately includes a clear warning about not using this option in production, which is essential for security. The examples and explanation are thorough.


121-129: Clear documentation for --instance-id property

The --instance-id property is well-documented with a thorough explanation of its purpose and usage scenarios. The examples illustrate how to use this property effectively.


217-228: Well-explained --prometheus-port property

The documentation for the new --prometheus-port property clearly explains how to enable and configure Prometheus metrics exposure. The examples cover common scenarios, providing users with good guidance.


230-238: Updated --color property with new default value

The documentation for the --color property has been updated to reflect the new default value of true. The explanation provides clear guidance on when to enable or disable this feature.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~233-~233: Possible missing comma found.
Context: ...eful for local development and debugging but may need to be disabled in production e...

(AI_HYDRA_LEO_MISSING_COMMA)


240-251: Clear Redis configuration documentation

The Redis configuration section clearly explains the purpose of Redis in the system (rate-limiting and distributed counters) and provides good examples of connection strings for different deployment scenarios.


281-287: Updated Docker Compose example with new configuration

The Docker Compose example has been updated to include new configuration options like UNKEY_PLATFORM, UNKEY_IMAGE, UNKEY_REDIS_URL, and UNKEY_PROMETHEUS_PORT, reflecting the changes in the configuration schema.


290-303: Improved AWS ECS example

The AWS ECS example has been updated to include the new configuration options like --image, --redis-url, --otel, and --prometheus-port, which helps users understand how to configure the API in a production AWS environment.

go/cmd/api/main.go (5)

17-38: Well-organized server configuration flags with clear descriptions

The server configuration flags are now well-structured with concise descriptions. The addition of http-port, color, and test-mode flags makes the API configuration more explicit and user-friendly.


40-66: Instance identification flags are properly documented

The instance identification flags now have clearer usage descriptions that explain their purpose in logging and metrics. Good organization with appropriate section comments.


68-80: Clear database configuration with appropriate requirements

The database configuration flags are well structured with the primary database properly marked as required. The readonly replica option is optional with a clear description of its purpose for reducing load on the primary database.


82-94: Improved caching and storage configuration

The Redis URL flag now clearly indicates its purpose for rate-limiting and distributed counters, which aligns with the PR objective of cleaning up after changing the ratelimit implementation.


96-116: Simplified observability configuration

The observability configuration flags now have more concise descriptions that focus on the essential information. The configuration options for OpenTelemetry and Prometheus are clearly defined.

go/go.mod (2)

5-31: Updated direct dependencies to latest versions

The direct dependencies have been updated to their latest versions, including ClickHouse, MySQL driver, and OpenTelemetry packages. This is good practice for security and performance improvements.


33-153: Updated indirect dependencies

The indirect dependencies have been properly updated to match the direct dependency changes. Pay special attention to the OpenTelemetry packages (lines 127-130) which are part of the metrics collection changes mentioned in the PR title.

go/apps/api/run.go (1)

132-137: Configuration simplified by removing InstanceID parameter

The InstanceID parameter has been removed from the zen.Config struct, which aligns with the broader removal of clustering features mentioned in the PR summary. This simplification maintains logging context while streamlining the server configuration.

go/pkg/db/queries/permission_find_by_workspace_and_name.sql (1)

1-3: Well-structured query for permission lookup

The new SQL query looks good. It correctly uses parameterized queries via sqlc.arg() to prevent SQL injection and provides a clear, focused query for finding permissions by workspace and name.

go/pkg/testutil/http.go (2)

55-55: Test database configuration improved with container reuse

Adding WithReuse(true) and WithPurge(false) parameters to RunMySQL improves test efficiency by reusing MySQL containers across tests rather than recreating them each time.


72-77: Server configuration simplified by removing InstanceID parameter

Consistent with changes in the main API server configuration, the InstanceID parameter has been removed from the test server configuration, ensuring testing matches production behavior.

go/internal/services/ratelimit/bucket.go (2)

8-8: Metrics package updated to use Prometheus

The import has been updated from the internal metrics package to the Prometheus metrics package, aligning with the PR's goal of migrating from OpenTelemetry to Prometheus for metrics collection.


101-101: Simplified metrics recording with Prometheus

The metrics recording has been updated to use Prometheus's simpler Inc() method instead of the previous OpenTelemetry approach that required a context parameter. This simplifies the code while maintaining the same functionality.

go/pkg/db/querier_generated.go (1)

99-103: New SQL query interface method looks good.

This addition to the Querier interface provides a way to retrieve a permission by both workspace ID and name, which is a useful query for permission management. The method is properly documented with the SQL query details in the comments.

go/pkg/zen/middleware_metrics.go (1)

65-69: Successfully migrated from OpenTelemetry to Prometheus metrics.

The implementation correctly switches from OpenTelemetry to Prometheus metrics for HTTP request tracking. The changes properly capture method, path, and status in label values for both request counts and latency observations.

go/pkg/prometheus/metrics/http.go (1)

1-67: Well-designed Prometheus metrics implementation.

The new HTTP metrics implementation provides:

  1. Well-documented histogram buckets optimized for web service latencies
  2. Clear metrics naming with proper subsystem prefixes
  3. Good documentation with usage examples
  4. Consistent labeling approach with method, path, and status

The granularity of the latency buckets is appropriate for web service monitoring, capturing everything from 1ms to 10s requests.

go/Taskfile.yml (6)

14-14: Added Redis as a dependency

Adding redis:latest to the pull task is consistent with the broader changes in this PR to use Redis for rate limiting instead of the previous clustered approach.


17-19: Good addition of a Docker build task

Adding a dedicated task for building the Docker image improves the build process organization and allows it to be referenced as a dependency in other tasks.


24-24: Ensures Docker image is built before tests

Adding the build-docker dependency to the test-full task ensures that the image is built before running the full test suite, which likely includes integration tests that require this image.


29-32: Improved test command with better feedback

The added echo command provides useful information about test duration and alternatives. The updated test command now includes shuffle and additional parameters for better test coverage and reliability.


36-36: Explicit skip of integration tests in unit test task

Adding the -skip "^TestIntegration_" flag to the unit test task creates a clearer separation between unit and integration tests, which should speed up the development cycle.


45-45:

Details

❓ Verification inconclusive

Confirm if buf generate is still needed

The buf generate command has been commented out. Ensure this is intentional and won't break any code generation needs.


🏁 Script executed:

#!/bin/bash
# Check if buf is still used in the codebase
echo "Checking for buf configuration files..."
fd -t f "buf.yaml|buf.gen.yaml|buf.work.yaml"

echo "Checking for imports or uses of buf-generated code..."
rg -i "buf.build|generated/buf" --type go

Length of output: 369


Review: Confirm Buf Code Generation and Usage

  • The repository still contains Buf configuration files in both apps/agent and go (i.e., buf.yaml and buf.gen.yaml), suggesting Buf is still set up.
  • No occurrences of Buf-generated code references (like "buf.build" or "generated/buf") were located in the Go files.
  • The buf generate command remains commented out in go/Taskfile.yml (line 45).

Please confirm whether:

  • Buf code generation is invoked elsewhere or handled manually, making the commented command intentional.
  • Alternatively, if the generation is essential to the build process, the command should be uncommented (or the configuration files removed if no longer needed).
go/internal/services/ratelimit/janitor.go (4)

6-6: Migration from OpenTelemetry to Prometheus metrics

The import has been updated to use Prometheus metrics instead of OpenTelemetry, which is consistent with the overall migration pattern in this PR.


44-44: Type change from int64 to float64 for metrics

Changed the type of windows variable from int64 to float64 to align with Prometheus conventions, which uses float64 for all metric values.


51-51: Simplified counter metrics with Prometheus Inc() method

Updated the metrics recording for evicted windows and buckets to use the simpler Inc() method instead of Add(ctx, 1). This eliminates context dependency and is more idiomatic for Prometheus.

Also applies to: 58-58


64-65: Updated gauge metrics to use Prometheus Set() method

Changed the gauge metrics for buckets and windows count to use the Set() method instead of Record(), eliminating context dependency and making the code more aligned with Prometheus patterns.

go/internal/services/ratelimit/replay.go (2)

9-9: Migration from OpenTelemetry to Prometheus metrics

The import has been updated to use Prometheus metrics instead of OpenTelemetry, which is consistent with the overall migration pattern in this PR.


50-50: Updated histogram metrics to use Prometheus Observe() method with seconds

Changed the latency metrics to use the Prometheus Observe() method instead of Record() and switched from milliseconds to seconds as the time unit, which is the Prometheus convention for time-based metrics.

deployment/docker-compose.yaml (1)

59-59: Replaced clustering configuration with direct Redis URL

The environment variables related to clustering (UNKEY_CLUSTER, UNKEY_CLUSTER_GOSSIP_PORT, UNKEY_CLUSTER_RPC_PORT, and UNKEY_CLUSTER_DISCOVERY_REDIS_URL) have been removed and replaced with a direct Redis connection URL. This aligns with the PR objective of cleaning up after changing the rate limit implementation to use Redis directly instead of clustering.

go/pkg/db/permission_find_by_workspace_and_name.sql_generated.go (1)

26-38: Handle "no rows" scenario
You might want to check if err == sql.ErrNoRows and handle it explicitly. Returning an error for an empty result can cause confusion for upstream code.

go/pkg/cache/cache.go (3)

68-70: Good approach tracking deletions
Incrementing a metric on cache deletion is helpful for observability.


163-170: Potential concurrency risk with shared timer
prometheus.NewTimer(...) usage is fine, but confirm that timing every concurrent request won't cause overhead or lock contention.


239-239: Revalidation metric
Incrementing the CacheRevalidations metric is beneficial for tracking usage. Continue to monitor concurrency safety if revalidations spike under heavy load.

go/apps/api/integration/multi_node_ratelimiting/run.go (1)

61-63: Check for integer overflow
Ensure integer operations in calculateRPS(limit, duration, loadFactor) don’t overflow when handling large values for limit or duration.

go/pkg/testutil/containers/mysql.go (6)

16-19: Well-designed container configuration struct

The new containerConfig struct provides a clean way to configure MySQL container behavior with reuse and purge options.


21-33: Good implementation of functional options pattern

The apply type and companion functions WithReuse and WithPurge follow the idiomatic Go functional options pattern, making the API both flexible and readable.


81-93: Clean function signature update with proper defaults

The updated function signature with variadic options and appropriate defaults (reuse=false, purge=true) maintains backward compatibility while adding new functionality.


95-106: Smart container naming strategy for reuse

Using a fixed name "mysql-reuse" when the reuse flag is true ensures consistency across test runs, while the dynamic test-specific naming is preserved for non-reuse cases.


127-132: Conditional resource cleanup based on configuration

The cleanup function now properly respects the purge flag, allowing resources to persist when needed without changing the core behavior.


163-179: Optimization: Skip schema creation for reused containers

Good performance optimization by only creating the database schema when starting a new container, not when reusing an existing one.

go/pkg/prometheus/metrics/cache.go (5)

1-12: Well-documented metrics package

Clear package documentation that explains the purpose of the metrics collection.


13-43: Comprehensive cache hit/miss tracking

The CacheHits and CacheMisses metrics provide essential visibility into cache efficiency with good example usage documentation.


44-73: Detailed cache operation metrics

The CacheWrites and CacheDeleted metrics offer granular tracking of write operations and deletions with appropriate labeling.


94-134: Well-structured cache capacity and revalidation metrics

The CacheSize, CacheCapacity, and CacheRevalidations metrics provide comprehensive monitoring capabilities for cache maintenance and optimization.


84-92:

Details

✅ Verification successful

Verify latencyBuckets variable is defined

The CacheReadLatency metric uses latencyBuckets which isn't defined in this file. Ensure this variable is defined elsewhere in the package.


🏁 Script executed:

#!/bin/bash
# Check if latencyBuckets is defined elsewhere in the prometheus/metrics package

echo "Searching for latencyBuckets definition in metrics package..."
rg --type go "var\s+latencyBuckets" go/pkg/prometheus/metrics/
echo "Searching for latencyBuckets initialization..."
rg --type go "latencyBuckets\s*=" go/pkg/prometheus/metrics/

Length of output: 495


Verified: latencyBuckets is defined in the package

The latencyBuckets variable is indeed defined in the package (located in go/pkg/prometheus/metrics/http.go), so no changes are needed in cache.go.

go/pkg/prometheus/metrics/ratelimit.go (4)

1-12: Well-documented rate limiting metrics package

Clear package documentation that explains the purpose of the rate limiting metrics collection.


13-91: Comprehensive rate limit resource tracking

Good coverage of metrics for tracking the lifecycle and resource usage of rate limiting components (buckets and windows).


93-130: Detailed decision-making metrics

The metrics for tracking local vs. origin decisions and refreshes provide valuable insights into distributed rate limiter behavior.


140-147:

Details

✅ Verification successful

Verify latencyBuckets variable is defined

The RatelimitOriginSyncLatency metric uses latencyBuckets which isn't defined in this file. Ensure this variable is defined elsewhere in the package.


🏁 Script executed:

#!/bin/bash
# Check if latencyBuckets is defined elsewhere in the prometheus/metrics package

echo "Searching for latencyBuckets definition in metrics package..."
rg --type go "var\s+latencyBuckets" go/pkg/prometheus/metrics/
echo "Searching for latencyBuckets initialization..."
rg --type go "latencyBuckets\s*=" go/pkg/prometheus/metrics/

Length of output: 495


LatencyBuckets Definition Verified

  • Confirmed that latencyBuckets is defined in go/pkg/prometheus/metrics/http.go (using var latencyBuckets = []float64{ ... }).

No further action is needed for this code segment.

Comment on lines +125 to +140
mysqlErr := &mysql.MySQLError{} // nolint:exhaustruct
if errors.As(err, &mysqlErr) {
// Error 1062 (23000): Duplicate entry
if mysqlErr.Number == 1064 {
existing, findErr := db.Query.FindPermissionByWorkspaceAndName(ctx, s.DB.RO(), db.FindPermissionByWorkspaceAndNameParams{
WorkspaceID: s.Resources.RootWorkspace.ID,
Name: permission,
})
require.NoError(s.t, findErr)
s.t.Logf("found existing permission: %+v", existing)
permissionID = existing.ID
}

} else {
require.NoError(s.t, err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect MySQL error code for duplicate entries.

The error handling for duplicate entries is checking for the wrong MySQL error code. Error code 1064 is for SQL syntax errors, not duplicate entries. The correct error code for duplicate entries in MySQL is 1062.

-				if mysqlErr.Number == 1064 {
+				if mysqlErr.Number == 1062 {
📝 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.

Suggested change
mysqlErr := &mysql.MySQLError{} // nolint:exhaustruct
if errors.As(err, &mysqlErr) {
// Error 1062 (23000): Duplicate entry
if mysqlErr.Number == 1064 {
existing, findErr := db.Query.FindPermissionByWorkspaceAndName(ctx, s.DB.RO(), db.FindPermissionByWorkspaceAndNameParams{
WorkspaceID: s.Resources.RootWorkspace.ID,
Name: permission,
})
require.NoError(s.t, findErr)
s.t.Logf("found existing permission: %+v", existing)
permissionID = existing.ID
}
} else {
require.NoError(s.t, err)
}
mysqlErr := &mysql.MySQLError{} // nolint:exhaustruct
if errors.As(err, &mysqlErr) {
// Error 1062 (23000): Duplicate entry
if mysqlErr.Number == 1062 {
existing, findErr := db.Query.FindPermissionByWorkspaceAndName(ctx, s.DB.RO(), db.FindPermissionByWorkspaceAndNameParams{
WorkspaceID: s.Resources.RootWorkspace.ID,
Name: permission,
})
require.NoError(s.t, findErr)
s.t.Logf("found existing permission: %+v", existing)
permissionID = existing.ID
}
} else {
require.NoError(s.t, err)
}

@chronark chronark disabled auto-merge April 8, 2025 07:03
@chronark chronark merged commit 018b383 into main Apr 8, 2025
30 of 37 checks passed
@chronark chronark deleted the clean-ratelimits branch April 8, 2025 07:04
@coderabbitai coderabbitai bot mentioned this pull request Aug 22, 2025
18 tasks
@coderabbitai coderabbitai bot mentioned this pull request Oct 21, 2025
18 tasks
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.

1 participant