Skip to content

fix(nodes): add rate limiting to tool_http_request node#560

Merged
stepmikhaylov merged 3 commits into
rocketride-org:developfrom
charliegillet:fix/http-request-rate-limiting
Apr 8, 2026
Merged

fix(nodes): add rate limiting to tool_http_request node#560
stepmikhaylov merged 3 commits into
rocketride-org:developfrom
charliegillet:fix/http-request-rate-limiting

Conversation

@charliegillet
Copy link
Copy Markdown
Contributor

@charliegillet charliegillet commented Mar 31, 2026

Summary

  • Add configurable rate limiting (per-second, per-minute, max-concurrent) to the tool_http_request node using a thread-safe token-bucket algorithm
  • Rate limit parameters are exposed in services.json with sensible defaults (10/s, 100/m, 5 concurrent)
  • Clear RateLimitError messages returned when any limit is breached

Type

Security Fix

Why this feature fits this codebase

Without rate limiting, an AI agent using tool_http_request can fire unlimited outbound HTTP requests. This creates several abuse vectors:

  • Denial-of-service amplification: a prompt-injected agent could flood a third-party API, burning the target's rate limits or triggering IP bans against the RocketRide deployment
  • Resource exhaustion: unbounded concurrent requests can exhaust file descriptors, connection pools, and memory on the RocketRide server itself
  • Cost explosion: agents calling metered APIs (OpenAI, Stripe, etc.) with no throttle can rack up unexpected bills

The existing guardrails (URL whitelist + method allowlist) control where requests go but not how fast. Rate limiting closes this gap.

What changed

File Change
rate_limiter.py New. Token-bucket rate limiter with a threading.Semaphore for concurrency control. Enforces per-second, per-minute, and max-concurrent limits.
http_driver.py _tool_invoke now calls rate_limiter.acquire() before the request and release() in a finally block. HttpDriver.__init__ accepts an optional RateLimiter.
IGlobal.py _build_rate_limiter() reads rateLimitPerSecond, rateLimitPerMinute, and maxConcurrentRequests from node config and constructs the limiter. Passed into HttpDriver.
services.json Three new config fields added to the "Pipe" section so operators can tune limits from the UI.
http_client.py Minor ruff auto-fix (removed blank line after docstring, D202).

Validation

  • ruff format and ruff check pass on all changed files (only pre-existing D107 in http_driver.py remains)
  • Token bucket math verified: refill rate = capacity / window, so 10 req/s refills at 10 tokens/s and 100 req/m refills at ~1.67 tokens/s
  • Concurrency semaphore uses non-blocking acquire(blocking=False) to fail fast rather than queue

How to extend

  • Swap in a Redis-backed limiter for multi-instance deployments by replacing RateLimiter with a distributed implementation behind the same acquire()/release() interface
  • Add per-URL-pattern rate limits by creating multiple RateLimiter instances keyed on the whitelist pattern

Closes: N/A — new contribution, no pre-existing issue

#Hack-with-bay-2

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added HTTP request rate limiting: configurable per-second, per-minute, and max concurrent request limits (defaults: 10/sec, 100/min, 5 concurrent) exposed in the HTTP Request node settings; enforced around outbound requests.
  • Tests
    • Added comprehensive tests covering token-bucket behavior, concurrency gating, refill semantics, and multithreaded scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a token-bucket rate limiter with concurrency control to the HTTP Request node, initializes it from global configuration, enforces limits around outbound requests, exposes three new config knobs, and includes unit tests for limiter behavior and concurrency.

Changes

Cohort / File(s) Summary
Rate Limiter Core
nodes/src/nodes/tool_http_request/rate_limiter.py
New thread-safe token-bucket + semaphore implementation (RateLimiter) with RateLimitError and defaults for per-second, per-minute, and concurrent limits.
Global state & config handling
nodes/src/nodes/tool_http_request/IGlobal.py, nodes/src/nodes/tool_http_request/services.json
Adds nullable rate_limiter to global state, helpers to parse integer config values, builder for RateLimiter from config; exposes http_request.rateLimitPerSecond, http_request.rateLimitPerMinute, and http_request.maxConcurrentRequests in schema (defaults 10/100/5).
Request integration
nodes/src/nodes/tool_http_request/IInstance.py
Wraps outbound HTTP call with IGlobal.rate_limiter.acquire() and guaranteed release() in finally when a rate limiter is present.
Tests & test infra
nodes/test/tool_http_request/test_rate_limiter.py, nodes/test/tool_http_request/conftest.py, nodes/test/tool_http_request/__init__.py
New comprehensive limiter tests (capacity, refill, concurrency, accounting, multithreaded smoke); small conftest import path adjustment; added test package header.
Minor formatting
nodes/src/nodes/tool_http_request/http_client.py
Whitespace adjustment around execute_request docstring and helper placement; no functional changes.

Sequence Diagram(s)

sequenceDiagram
  participant Instance as IInstance
  participant Global as IGlobal
  participant Limiter as RateLimiter
  participant Client as HTTP Client

  Instance->>Global: read rate_limiter
  alt rate_limiter exists
    Instance->>Limiter: acquire()
    note right of Limiter: semaphore + token-buckets\nper-second & per-minute checks
    Limiter-->>Instance: success / RateLimitError
    alt success
      Instance->>Client: execute_request(...)
      Client-->>Instance: response / error
      Instance->>Limiter: release()
    else RateLimitError
      Instance-->>Client: propagate error (no request sent)
    end
  else no rate_limiter
    Instance->>Client: execute_request(...) (no rate limiting)
    Client-->>Instance: response / error
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • jmaionchi
  • Rod-Christensen

Poem

🐰 I hop the tokens, guard each tiny flight,
Buckets that tickle day and minute light,
Semaphores hold the bustling crowd,
Requests queue soft, not screaming loud,
A gentle pace — and all is bright. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix(nodes): add rate limiting to tool_http_request node' directly and clearly describes the main change: adding rate limiting functionality to the HTTP request node.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the module:nodes Python pipeline nodes label Mar 31, 2026
Copy link
Copy Markdown
Collaborator

@asclearuc asclearuc left a comment

Choose a reason for hiding this comment

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

Review: PR #560 — Rate limiting for tool_http_request

The feature is well-motivated and the overall structure (token bucket + semaphore, config-driven via services.json) is solid. However there is a logic bug in the core algorithm that must be fixed before merge, plus a mandatory project rule violation.

No unit tests: the refill math and three-way acquire() logic are non-trivial. The bug above is exactly what a unit test would catch. Please add tests for: normal acquire/release, per-second enforcement, per-minute enforcement, semaphore exhaustion, and token restoration on semaphore rejection.

Comment thread nodes/src/nodes/tool_http_request/IGlobal.py Outdated
Comment thread nodes/src/nodes/tool_http_request/rate_limiter.py
Comment thread nodes/src/nodes/tool_http_request/http_driver.py Outdated
Comment thread nodes/src/nodes/tool_http_request/IGlobal.py Outdated
charliegillet added a commit to charliegillet/rocketride-server that referenced this pull request Apr 3, 2026
…miter

- Fix critical bug: check semaphore BEFORE consuming tokens so rejected
  requests don't wastefully consume rate-limit tokens. Release semaphore
  if token check fails afterward.
- Extract _config_int() utility with min_value/max_value clamping params
  from inline _int_or_default helper in IGlobal._build_rate_limiter.
- Allow _build_rate_limiter to return None when all three rate-limit
  knobs are explicitly set to 0 (opt-out path).
- Remove unused RateLimitError import with noqa:F401 from http_driver.py.
- Add unit tests covering: normal acquire/release, per-second enforcement,
  per-minute enforcement, semaphore exhaustion, token restoration on
  semaphore rejection, and thread safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nodes/src/nodes/tool_http_request/IGlobal.py`:
- Around line 135-162: The current _build_rate_limiter() implements an
"all-or-nothing" opt-out via the helper _is_zero (all three raw_* must be
explicitly 0) while _config_int silently falls back to defaults when a user
supplies a non-None value <= 0; update _build_rate_limiter to warn when a raw
value was provided but clamped/reverted by _config_int: inspect
raw_ps/raw_pm/raw_mc, and for any raw that is not None and parses to an int <= 0
(use the same parsing logic as _is_zero), emit a clear warning message via the
module logger mentioning the offending field name (e.g. 'rateLimitPerSecond')
and that it will be treated as the default; keep the overall opt-out behavior
and continue using _config_int/RateLimiter/DEFAULT_* as currently implemented.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6dcf87de-05a3-497c-ba9f-70eeceff1ca4

📥 Commits

Reviewing files that changed from the base of the PR and between b6b2dc1 and a0c7f46.

📒 Files selected for processing (6)
  • nodes/src/nodes/tool_http_request/IGlobal.py
  • nodes/src/nodes/tool_http_request/http_client.py
  • nodes/src/nodes/tool_http_request/http_driver.py
  • nodes/src/nodes/tool_http_request/rate_limiter.py
  • nodes/src/nodes/tool_http_request/services.json
  • nodes/test/test_rate_limiter.py

Comment thread nodes/src/nodes/tool_http_request/IGlobal.py
@charliegillet
Copy link
Copy Markdown
Contributor Author

Addressed all review feedback:

  • Fixed critical bug: semaphore checked before consuming tokens, with proper token restoration on rejection
  • Extracted _config_int() as module-level utility with min_value/max_value clamping
  • _build_rate_limiter now returns None when all three knobs are set to 0 (opt-out path)
  • Removed unused RateLimitError import and # noqa: F401 from http_driver.py
  • Added comprehensive unit tests for all rate limiter scenarios

Thanks for the review!

Copy link
Copy Markdown
Collaborator

@asclearuc asclearuc left a comment

Choose a reason for hiding this comment

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

Thanks @charliegillet.

However, since this was authored, PR #599 landed and replaced the tool node architecture that this PR was built on.

This PR needs to be rebuilt against the new pattern before it can merge.

charliegillet added a commit to charliegillet/rocketride-server that referenced this pull request Apr 6, 2026
…miter

- Fix critical bug: check semaphore BEFORE consuming tokens so rejected
  requests don't wastefully consume rate-limit tokens. Release semaphore
  if token check fails afterward.
- Extract _config_int() utility with min_value/max_value clamping params
  from inline _int_or_default helper in IGlobal._build_rate_limiter.
- Allow _build_rate_limiter to return None when all three rate-limit
  knobs are explicitly set to 0 (opt-out path).
- Remove unused RateLimitError import with noqa:F401 from http_driver.py.
- Add unit tests covering: normal acquire/release, per-second enforcement,
  per-minute enforcement, semaphore exhaustion, token restoration on
  semaphore rejection, and thread safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@charliegillet charliegillet force-pushed the fix/http-request-rate-limiting branch from a0c7f46 to c173873 Compare April 6, 2026 18:17
@charliegillet
Copy link
Copy Markdown
Contributor Author

Rebased on develop and migrated to the @tool_function decorator pattern from PR #599. Removed the HttpDriver(ToolsBase) approach and integrated rate limiting directly into the @tool_function http_request method on IInstance, with the RateLimiter stored on IGlobal. The rate_limiter.py module is unchanged. Ready for re-review. Thanks for the guidance!

@charliegillet
Copy link
Copy Markdown
Contributor Author

Addressing @asclearuc's inline feedback:

  1. _config_int as library utility — Good suggestion. Extracted it as a module-level helper in IGlobal for now. Can be moved to a shared library utils module in a follow-up if other nodes need it.

  2. Token consumption before semaphore check — Fixed in the rebase. The rate limiter now checks the concurrency semaphore first (non-blocking), and only consumes tokens if the semaphore was acquired. If tokens are insufficient, the semaphore is released before raising the error.

  3. RateLimitError re-export — Cleaned up in the migration. The old http_driver.py is removed; RateLimitError is used directly in rate_limiter.py.

  4. Opt-out of rate limiting — Fixed: _build_rate_limiter now returns None when all three config values are explicitly set to 0, and IInstance checks for None before calling acquire/release.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nodes/test/test_rate_limiter.py`:
- Around line 18-23: The test currently mutates sys.path in test_rate_limiter.py
using sys.path.insert(...) to import rate_limiter; move this path setup into a
reusable pytest fixture or conftest.py so multiple tests can reuse it: create a
conftest.py that defines a session-scoped fixture (or module import-time setup)
which adds Path(__file__).resolve().parent.parent / 'src' / 'nodes' /
'tool_http_request' to sys.path before tests run, and update
test_rate_limiter.py to remove the inline sys.path modification and simply
import RateLimiter and RateLimitError; reference the existing sys.path.insert
call and the imports from rate_limiter to locate where to remove and replace
with the conftest-managed setup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 688b4aa2-1f12-4235-a573-6e9462a106eb

📥 Commits

Reviewing files that changed from the base of the PR and between a0c7f46 and c173873.

📒 Files selected for processing (6)
  • nodes/src/nodes/tool_http_request/IGlobal.py
  • nodes/src/nodes/tool_http_request/IInstance.py
  • nodes/src/nodes/tool_http_request/http_client.py
  • nodes/src/nodes/tool_http_request/rate_limiter.py
  • nodes/src/nodes/tool_http_request/services.json
  • nodes/test/test_rate_limiter.py

Comment thread nodes/test/test_rate_limiter.py
@nihalnihalani
Copy link
Copy Markdown
Contributor

Senior Review — PR #560: fix(nodes): add rate limiting to tool_http_request

@charliegillet, great initiative here — proactively rebasing onto the new @tool_function architecture from PR #599 shows good awareness of the evolving codebase. That saves everyone a round of merge conflicts later.

Status: With the rebase complete and tests added, this looks ready for a re-review.

One suggestion: Now that the tests are in place, it would be worth verifying the token-bucket math explicitly. Specifically:

  • Confirm that the refill rate and bucket capacity interact correctly at boundary conditions (e.g., burst immediately after bucket drains, requests arriving exactly at the refill interval).
  • Verify that the rate limiter state resets appropriately across node invocations if that's the intended behavior.

If the existing tests already cover these edge cases, great — just flagging it as a sanity check given that rate limiting bugs tend to be subtle and only surface under load.

This is looking close. A re-review should be able to move this forward.

@nihalnihalani
Copy link
Copy Markdown
Contributor

🚀 Merge Request

Author has proactively rebased onto the new @tool_function architecture from PR #599 and added tests.

Status: Looks ready for re-review and merge. Please verify the token-bucket implementation against the new pattern. @asclearuc

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 8, 2026

No description provided.

@charliegillet
Copy link
Copy Markdown
Contributor Author

All review feedback has been addressed. Here's a summary:

Rebase on #599: The branch was already rebased on develop (which includes #599). The rate limiter integrates cleanly with the new @tool_function pattern — acquire()/release() wrap the execute_request() call inside IInstance.http_request() with a try/finally block. The rate_limiter.py module is architecture-agnostic (pure token-bucket + semaphore), so no rewrite was needed.

Previously addressed (commits b5eeac0, c173873):

  • _config_int extracted as utility with min/max clamping
  • Semaphore checked before token consumption (with release on token rejection)
  • Unused RateLimitError import removed
  • _build_rate_limiter returns Optional[RateLimiter]
  • 10 unit tests covering: acquire/release, per-second enforcement, per-minute enforcement, semaphore exhaustion, token restoration on semaphore rejection, thread safety

New commit (cdd2fdb):

  • Moved sys.path.insert from test file to conftest.py (CodeRabbit feedback)
  • Documented all-or-nothing opt-out behavior in services.json field descriptions (CodeRabbit feedback)

All tests pass, ruff check clean.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nodes/test/test_rate_limiter.py`:
- Around line 163-171: Add a return type annotation to the helper function
worker (declare it as returning None) and suppress the BLE001 warning for the
broad exception handler instead of changing behavior: keep the existing except
Exception as exc: errors.append(exc) but append a noqa comment for BLE001 on
that except line; locate the worker function wrapping rl.acquire()/rl.release()
and the except RateLimitError/except Exception as exc handlers to apply these
edits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 97777778-b54b-43ce-86d4-c1ce91fa58de

📥 Commits

Reviewing files that changed from the base of the PR and between c173873 and cdd2fdb.

📒 Files selected for processing (3)
  • nodes/src/nodes/tool_http_request/services.json
  • nodes/test/conftest.py
  • nodes/test/test_rate_limiter.py

Comment thread nodes/test/tool_http_request/test_rate_limiter.py
@charliegillet
Copy link
Copy Markdown
Contributor Author

Latest fixes

charliegillet and others added 2 commits April 8, 2026 16:27
Without rate limiting, the HTTP request node can be abused to flood
external APIs or exhaust server resources. This adds a token-bucket
rate limiter with three configurable limits: per-second, per-minute,
and max concurrent requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…miter

- Fix critical bug: check semaphore BEFORE consuming tokens so rejected
  requests don't wastefully consume rate-limit tokens. Release semaphore
  if token check fails afterward.
- Extract _config_int() utility with min_value/max_value clamping params
  from inline _int_or_default helper in IGlobal._build_rate_limiter.
- Allow _build_rate_limiter to return None when all three rate-limit
  knobs are explicitly set to 0 (opt-out path).
- Remove unused RateLimitError import with noqa:F401 from http_driver.py.
- Add unit tests covering: normal acquire/release, per-second enforcement,
  per-minute enforcement, semaphore exhaustion, token restoration on
  semaphore rejection, and thread safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@stepmikhaylov stepmikhaylov force-pushed the fix/http-request-rate-limiting branch from cdd2fdb to d66d1c8 Compare April 8, 2026 14:53
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nodes/src/nodes/tool_http_request/services.json`:
- Around line 114-130: Update the three schema entries
"http_request.rateLimitPerSecond", "http_request.rateLimitPerMinute", and
"http_request.maxConcurrentRequests" so their description strings explicitly
document the opt-out behavior; add the sentence "Set to 0 to disable (all three
rate-limit fields must be 0 to fully opt out)." to each description (or add it
to one description and reference the requirement from the other two) so users
know setting a single field to 0 does not disable that limit unless all three
are 0.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4eb122dd-6a3e-423a-aad6-9526448a1ef1

📥 Commits

Reviewing files that changed from the base of the PR and between cdd2fdb and d66d1c8.

📒 Files selected for processing (7)
  • nodes/src/nodes/tool_http_request/IGlobal.py
  • nodes/src/nodes/tool_http_request/IInstance.py
  • nodes/src/nodes/tool_http_request/http_client.py
  • nodes/src/nodes/tool_http_request/rate_limiter.py
  • nodes/src/nodes/tool_http_request/services.json
  • nodes/test/tool_http_request/conftest.py
  • nodes/test/tool_http_request/test_rate_limiter.py

Comment thread nodes/src/nodes/tool_http_request/services.json
@stepmikhaylov stepmikhaylov force-pushed the fix/http-request-rate-limiting branch from d66d1c8 to d7ba8e9 Compare April 8, 2026 15:06
@stepmikhaylov stepmikhaylov force-pushed the fix/http-request-rate-limiting branch from d7ba8e9 to cffaa9a Compare April 8, 2026 15:09
Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nodes/test/tool_http_request/test_rate_limiter.py`:
- Around line 1-4: Update the file header to match the repository standard by
replacing the existing "Copyright (c) 2024 RocketRide Inc." line with "Copyright
(c) 2026 Aparavi Software AG" (keep the surrounding MIT License header lines
intact); search for the exact string "Copyright (c) 2024 RocketRide Inc." in
this file and replace it so the header matches the other module (__init__.py) in
the same directory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5e227ecc-2469-41eb-9abc-688d8e3936dc

📥 Commits

Reviewing files that changed from the base of the PR and between d66d1c8 and d7ba8e9.

📒 Files selected for processing (3)
  • nodes/test/tool_http_request/__init__.py
  • nodes/test/tool_http_request/conftest.py
  • nodes/test/tool_http_request/test_rate_limiter.py

Comment thread nodes/test/tool_http_request/test_rate_limiter.py
@asclearuc asclearuc self-requested a review April 8, 2026 15:12
@stepmikhaylov stepmikhaylov enabled auto-merge (squash) April 8, 2026 15:14
@stepmikhaylov stepmikhaylov merged commit 084a111 into rocketride-org:develop Apr 8, 2026
16 checks passed
ryan-t-christensen pushed a commit that referenced this pull request Apr 8, 2026
* fix(nodes): add configurable rate limiting to tool_http_request node

Without rate limiting, the HTTP request node can be abused to flood
external APIs or exhaust server resources. This adds a token-bucket
rate limiter with three configurable limits: per-second, per-minute,
and max concurrent requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(nodes): address PR #560 review feedback for rate limiter

- Fix critical bug: check semaphore BEFORE consuming tokens so rejected
  requests don't wastefully consume rate-limit tokens. Release semaphore
  if token check fails afterward.
- Extract _config_int() utility with min_value/max_value clamping params
  from inline _int_or_default helper in IGlobal._build_rate_limiter.
- Allow _build_rate_limiter to return None when all three rate-limit
  knobs are explicitly set to 0 (opt-out path).
- Remove unused RateLimitError import with noqa:F401 from http_driver.py.
- Add unit tests covering: normal acquire/release, per-second enforcement,
  per-minute enforcement, semaphore exhaustion, token restoration on
  semaphore rejection, and thread safety.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore(nodes): move tool_http_request tests

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: stepmik <stepmikhaylov@yandex.ru>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module:nodes Python pipeline nodes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants