Skip to content

fix(client-typescript): implement documented maxConcurrent for sendFiles() (#1381)#1382

Open
anshvermadev wants to merge 12 commits into
rocketride-org:developfrom
anshvermadev:fix/RR-1381-sendfiles-maxconcurrent
Open

fix(client-typescript): implement documented maxConcurrent for sendFiles() (#1381)#1382
anshvermadev wants to merge 12 commits into
rocketride-org:developfrom
anshvermadev:fix/RR-1381-sendfiles-maxconcurrent

Conversation

@anshvermadev

@anshvermadev anshvermadev commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

sendFiles() advertised a maxConcurrent parameter (default 5) in its JSDoc and example, but the actual signature accepted only (files, token) and the implementation opened one data pipe per file with no concurrency cap.

This fixes the mismatch by implementing the documented behavior.

Closes #1381


Problem

Two concrete defects:

  1. Unbounded concurrency.
    Uploading N files opened N server-side data pipes simultaneously (files.map(...) + Promise.all), contrary to the documented default of 5. Large batches could exhaust pipes, sockets, or memory on both the client and server.

  2. Documented example didn't compile.
    Under the package's strict TypeScript configuration, the JSDoc example:

    client.sendFiles([...], "task-token", 10)

    failed with:

    TS2554: Expected 2 arguments, but got 3.
    

Fix

  • Added the maxConcurrent = 5 parameter to the sendFiles() signature, matching the JSDoc.
  • Replaced the unbounded files.map(...) + Promise.all dispatch with a bounded worker pool that keeps at most maxConcurrent uploads (and therefore data pipes) in flight at a time.
  • Result ordering is preserved — results are still written by index, so output order matches input order regardless of completion order.
  • Per-file errors are still caught so one failed upload doesn't kill the batch.

Testing

  • npx tsc --noEmit passes for packages/client-typescript (the documented 3-argument call now type-checks).
  • Ordering preserved by index-based writes; concurrency bounded to maxConcurrent.

Notes

  • No documentation changes required: the JSDoc example already documented the parameter — that discrepancy was the bug.
  • The generated reference under docs/reference/ is produced by client-typescript:docs-generate.

Summary by CodeRabbit

  • New Features

    • Added a configurable concurrency limit for batch file uploads (--max-concurrent / maxConcurrent), defaulting to 5 simultaneous uploads.
  • Bug Fixes

    • Batch upload results are returned in the same order as the input files.
    • Individual file upload failures no longer interrupt the rest of the batch.
  • Documentation

    • Updated TypeScript guide examples and parameter documentation to include maxConcurrent.

sendFiles() advertised a maxConcurrent parameter (default 5) in its JSDoc
and example, but the signature accepted only (files, token) and the
implementation opened one data pipe per file with no cap. Large batches
could exhaust pipes/sockets/memory, and the documented 3-argument call
failed to type-check (TS2554).

Add the maxConcurrent = 5 parameter and run uploads through a bounded
worker pool that keeps at most maxConcurrent uploads in flight. Results
are still written by index, so output order is preserved.

Closes rocketride-org#1381
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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

The TypeScript client now caps concurrent file uploads through a maxConcurrent argument, and the CLI forwards its concurrency option into that upload path.

Changes

sendFiles concurrency fix

Layer / File(s) Summary
Add bounded upload concurrency
packages/client-typescript/src/client/client.ts, packages/client-typescript/docs/guide/index.md, packages/client-typescript/docs/guide/methods/send.md
sendFiles gains an optional maxConcurrent parameter (default 5), switches to a bounded worker pool, and the TypeScript guide updates its signature, example, and parameter table.
CLI concurrency wiring
packages/client-typescript/src/cli/rocketride.ts
cmdUpload passes this.args.max_concurrent into sendFiles so the CLI option affects upload parallelism.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant sendFiles
  participant Worker
  participant uploadFile

  CLI->>sendFiles: sendFiles(files, token, maxConcurrent)
  sendFiles->>sendFiles: start bounded workers
  loop until next file index is exhausted
    sendFiles->>Worker: assign next file index
    Worker->>uploadFile: uploadFile(fileData, index)
    uploadFile-->>Worker: result
    Worker->>sendFiles: store results[index]
  end
  sendFiles-->>CLI: resolve with ordered results
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely describes the main change: adding maxConcurrent support to sendFiles().
Linked Issues check ✅ Passed The changes match #1381 by adding maxConcurrent, capping concurrency, preserving order, and supporting the documented 3-argument call.
Out of Scope Changes check ✅ Passed The edits stay within the sendFiles concurrency fix and related docs, with no unrelated feature work apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/client-typescript/src/client/client.ts (1)

1347-1355: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Public SDK signature change missing docs update.

sendFiles now takes a new public parameter maxConcurrent, but the linked docs snippet (packages/client-typescript/docs/guide/index.md) still shows the old (files, token) signature without maxConcurrent.

As per path instructions, packages/client-typescript/src/**/*.ts: "Update public TypeScript SDK signatures in packages/client-typescript/docs/ when changing the signature in code." Also per coding guidelines, packages/client-typescript/src/**/*.{ts,tsx}: "Public TypeScript SDK signature changes must be documented in packages/client-typescript/docs/ with reference documentation auto-generated by client-typescript:docs-generate."

Please regenerate/update the docs (e.g. run client-typescript:docs-generate) to reflect the new maxConcurrent parameter.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/client-typescript/src/client/client.ts` around lines 1347 - 1355,
The public `sendFiles` signature in `client.ts` now includes the new
`maxConcurrent` parameter, but the generated docs still show the old `files,
token` form. Update the TypeScript SDK reference docs under
`packages/client-typescript/docs/` by regenerating them (for example via
`client-typescript:docs-generate`) so the `sendFiles` documentation matches the
current signature and includes `maxConcurrent`.

Sources: Coding guidelines, Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/client-typescript/src/client/client.ts`:
- Around line 1466-1486: The bounded upload worker in client.ts’s sendFiles path
does not validate maxConcurrent before using it, so NaN or other non-finite
values can turn the pool length into zero and silently skip all uploads. Add an
explicit sanity check near the limit calculation in sendFiles (and/or before
Promise.all) to normalize only finite positive integers, or throw a clear error
when maxConcurrent is invalid, so uploadFile still runs for every file or fails
fast instead of returning empty results.
- Around line 1466-1486: Forward the parsed --max-concurrent value from the
upload command into sendFiles so the bounded pool in client.ts uses the
requested concurrency instead of always falling back to the default. Update
cmdUpload() in rocketride.ts to pass the third argument through to
sendFiles(fileObjects, taskToken!, maxConcurrent), matching the sendFiles worker
pool logic and its maxConcurrent parameter.

---

Outside diff comments:
In `@packages/client-typescript/src/client/client.ts`:
- Around line 1347-1355: The public `sendFiles` signature in `client.ts` now
includes the new `maxConcurrent` parameter, but the generated docs still show
the old `files, token` form. Update the TypeScript SDK reference docs under
`packages/client-typescript/docs/` by regenerating them (for example via
`client-typescript:docs-generate`) so the `sendFiles` documentation matches the
current signature and includes `maxConcurrent`.
🪄 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: c7513a56-3fdf-4574-95a0-1bcff69d0e59

📥 Commits

Reviewing files that changed from the base of the PR and between bea24f1 and befda3f.

📒 Files selected for processing (1)
  • packages/client-typescript/src/client/client.ts

Comment thread packages/client-typescript/src/client/client.ts
Address CodeRabbit review on rocketride-org#1381:

- sendFiles() now guards against non-finite/invalid maxConcurrent (e.g.
  NaN from an upstream parseInt on a malformed --max-concurrent flag).
  Previously NaN propagated through Math.min/Math.max, produced a
  zero-length worker array, and sendFiles resolved immediately without
  uploading anything. Invalid values now fall back to the documented
  default of 5; non-integers are floored.
- The upload CLI command now forwards --max-concurrent into sendFiles()
  instead of always using the default 5.
Address CodeRabbit outside-diff comment on rocketride-org#1381: the SDK guide still
showed the old (files, token) sendFiles() signature. Add the optional
maxConcurrent parameter (default 5) to the TypeScript signature in the
method reference table and to the send_files/sendFiles parameters table.
@github-actions github-actions Bot added the docs Documentation label Jul 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/client-typescript/docs/guide/methods/send.md`:
- Line 143: The `maxConcurrent` documentation in the `sendFiles()` guide does
not match the actual fallback behavior. Update the wording in the `sendFiles()`
docs table to reflect that only non-finite values fall back to `5`, while finite
out-of-range values are handled differently by the implementation, or adjust
`sendFiles()` so its concurrency logic matches the documented fallback. Use the
`sendFiles` symbol to locate the implementation and keep the docs aligned with
the runtime behavior.
🪄 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: 7b7e7a54-f3aa-4857-abef-5e82db1ca1df

📥 Commits

Reviewing files that changed from the base of the PR and between b9a4d65 and fed6f1a.

📒 Files selected for processing (2)
  • packages/client-typescript/docs/guide/index.md
  • packages/client-typescript/docs/guide/methods/send.md

Comment thread packages/client-typescript/docs/guide/methods/send.md Outdated
Address CodeRabbit comment on rocketride-org#1381: the parameter table claimed all
invalid values fall back to 5, but sendFiles() only falls back to 5 for
non-finite input; finite values are floored and clamped to at least 1.
Narrow the wording to describe the actual behavior.
dsapandora
dsapandora previously approved these changes Jul 2, 2026

@dsapandora dsapandora left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice, tight fix — good bug to catch too, since an undocumented unbounded-concurrency upload path is exactly the kind of thing that looks fine in dev and then falls over on a real batch of files.

The worker-pool implementation is clean: nextIndex++ dispatch, results written by index so ordering survives out-of-order completion, and per-file failures caught so one bad upload doesn't sink the batch. I like that you also fixed the CLI call site to pass --max-concurrent through instead of leaving it disconnected.

On CodeRabbit's NaN concern (client.ts:1490) — that's already handled here: Number.isFinite(maxConcurrent) ? Math.floor(maxConcurrent) : 5 catches NaN before it ever reaches Math.min/Array.from, so the "zero uploads, no error" scenario it describes doesn't actually happen in this diff. Their second comment (docs wording for finite-but-invalid values like 0/-1) is correctly marked addressed — the clamp-to-1 behavior matches what the docs now say.

Two minor things, neither blocking:

  • No test exercises the concurrency cap itself (e.g. asserting no more than maxConcurrent uploads are in flight at once) — worth a quick unit test if there's an existing harness for sendFiles, since this is the actual bug being fixed.
  • packages/client-typescript/docs/guide/index.md table row is now quite long (163+ chars) — pure formatting nit, not worth blocking on.

Looks good to merge.

@anshvermadev

Copy link
Copy Markdown
Contributor Author

@dsapandora or @asclearuc merge when ready!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/client-typescript/src/client/client.ts (2)

1484-1484: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use this.debugMessage for consistency with the rest of the class.

Every other error/log path in this class routes through this.debugMessage (e.g. Lines 1174, 1203, 1226); this is the only spot using raw console.error, which bypasses any consumer-side debug/trace hooks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/client-typescript/src/client/client.ts` at line 1484, Replace the
raw console.error in the upload failure path of client.ts with this.debugMessage
so it matches the rest of the Client class logging behavior and preserves
consumer-side debug/trace hooks. Locate the upload error handling around the
file upload flow in Client and route the failure message plus err through
this.debugMessage, following the pattern used by the other error paths in the
class.

1399-1448: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Close the pipe on upload errors
Failed uploads can leave the data pipe open on the server. send() already does best-effort cleanup, but uploadFile only records the error; if open() succeeds and write() or close() throws, the pipe stays allocated until server cleanup. Add a best-effort pipe.close() in the catch path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/client-typescript/src/client/client.ts` around lines 1399 - 1448,
The uploadFile flow records errors but does not clean up an opened pipe when
pipe.open(), pipe.write(), or pipe.close() fails. Update the catch path in
uploadFile to perform a best-effort pipe.close() whenever pipe was
created/opened, and ignore any cleanup failure so the original error is
preserved. Use the existing pipe variable and the surrounding try/catch/finally
logic in uploadFile to ensure server-side resources are released on failed
uploads.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/client-typescript/src/client/client.ts`:
- Line 1484: Replace the raw console.error in the upload failure path of
client.ts with this.debugMessage so it matches the rest of the Client class
logging behavior and preserves consumer-side debug/trace hooks. Locate the
upload error handling around the file upload flow in Client and route the
failure message plus err through this.debugMessage, following the pattern used
by the other error paths in the class.
- Around line 1399-1448: The uploadFile flow records errors but does not clean
up an opened pipe when pipe.open(), pipe.write(), or pipe.close() fails. Update
the catch path in uploadFile to perform a best-effort pipe.close() whenever pipe
was created/opened, and ignore any cleanup failure so the original error is
preserved. Use the existing pipe variable and the surrounding try/catch/finally
logic in uploadFile to ensure server-side resources are released on failed
uploads.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 67a48f9a-63d8-4f5f-a36e-9d34fa95cbe4

📥 Commits

Reviewing files that changed from the base of the PR and between f17b46a and 390f954.

📒 Files selected for processing (2)
  • packages/client-typescript/docs/guide/index.md
  • packages/client-typescript/src/client/client.ts

@anshvermadev

Copy link
Copy Markdown
Contributor Author

@dsapandora @asclearuc

@github-actions github-actions Bot added the module:nodes Python pipeline nodes label Jul 6, 2026
@github-actions github-actions Bot added the module:server C++ engine and server components label Jul 6, 2026
@github-actions

Copy link
Copy Markdown
Contributor
🤖 Internal: Discord sync marker

Auto-managed by the Discord notification workflow. Stores the linked Discord message ID and forum thread ID. Do not edit or delete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation module:client-typescript module:nodes Python pipeline nodes module:server C++ engine and server components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sendFiles() ignores its documented maxConcurrent argument

2 participants