Skip to content

feat(client): parallel git snapshot download with bounded in-memory streaming#360

Open
worstell wants to merge 1 commit into
mainfrom
worstell/parallel-get-stream
Open

feat(client): parallel git snapshot download with bounded in-memory streaming#360
worstell wants to merge 1 commit into
mainfrom
worstell/parallel-get-stream

Conversation

@worstell

@worstell worstell commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Downloads git snapshots with up to N concurrent range requests (--download-concurrency, default 8) reassembled in order by an in-memory StreamSink that pipes straight into zstd→tar extraction, so transfer and extraction overlap.

Memory is bounded regardless of snapshot size: the sink holds a fixed arena of 2×concurrency chunk buffers, and fetchers block once they are a full window ahead of the consumer, capping peak buffering at 2×concurrency×chunkSize — 256 MiB at the best-observed tuning of 16 MiB chunks × concurrency 8.

Chunks are pinned to the discovery response's ETag, so a mid-download rewrite fails the download rather than splicing bytes from different object versions. Servers without range support, objects without ETags, and small objects fall back transparently to a single streaming request. Extraction goes to a staging directory renamed into place only on success, so a failed download cannot leave a half-written checkout.

End-to-end benchmarking against a real multi-replica deployment showed this in-memory streaming approach consistently outperformed disk-backed reassembly (ring buffer and spill-file variants, which lack backpressure or pay a disk round-trip), restoring large repositories 1.4–2.8× faster than the sequential baseline.

@worstell worstell force-pushed the worstell/parallel-get-stream branch from 4d97fb3 to 83e3e16 Compare June 26, 2026 00:30
@worstell worstell changed the title feat(client): add ParallelGetStream for in-order streaming parallel downloads feat(client): stream ParallelGet in-order to an io.Writer Jun 26, 2026
@worstell worstell force-pushed the worstell/parallel-get-stream branch 2 times, most recently from 250ab5b to 5eaaa77 Compare June 29, 2026 17:50
@worstell worstell changed the title feat(client): stream ParallelGet in-order to an io.Writer feat(client): parallel git snapshot download APIs Jun 29, 2026
@worstell worstell force-pushed the worstell/parallel-get-stream branch from 5eaaa77 to 4f7efa2 Compare June 29, 2026 18:24
@worstell worstell marked this pull request as ready for review June 29, 2026 18:34
@worstell worstell requested a review from a team as a code owner June 29, 2026 18:34
@worstell worstell requested review from alecthomas and removed request for a team June 29, 2026 18:34
@alecthomas

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f7efa2a0d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread client/git.go Outdated
@worstell worstell force-pushed the worstell/parallel-get-stream branch 2 times, most recently from e5f6506 to 7b4044b Compare June 30, 2026 00:07
@worstell

Copy link
Copy Markdown
Contributor Author

@codex review

@worstell worstell force-pushed the worstell/parallel-get-stream branch from 7b4044b to 882efc2 Compare June 30, 2026 00:11

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b4044bbd6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/git.go Outdated
Comment thread client/parallel_get.go Outdated
@worstell worstell force-pushed the worstell/parallel-get-stream branch from 882efc2 to 011f22c Compare June 30, 2026 00:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 011f22ce30

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/cachew/git.go
Comment thread client/git_test.go Outdated
@worstell worstell force-pushed the worstell/parallel-get-stream branch from 011f22c to 8097115 Compare June 30, 2026 02:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8097115117

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/parallel_get.go Outdated
Comment thread client/chunk_sink.go Outdated
Comment on lines +76 to +81
// Place reads the chunk into its slot and queues it for in-order delivery to
// Read. It blocks until the chunk is within one window of the read cursor
// (backpressure from a slow consumer) and aborts if ctx is cancelled. A negative
// length switches to pass-through mode: the whole body is handed to Read
// directly, since a single-stream fallback has unknown size and must not be
// buffered.

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.

Why does Amp always ignore the commenting instructions in the AGENTS.md in this repo? These comments are obscenely long.

Comment thread client/chunk_sink.go Outdated
@worstell worstell marked this pull request as draft June 30, 2026 23:09
@worstell worstell closed this Jul 7, 2026
@worstell worstell reopened this Jul 7, 2026
@worstell worstell force-pushed the worstell/parallel-get-stream branch 2 times, most recently from c131050 to 084150b Compare July 10, 2026 23:19
@worstell worstell changed the title feat(client): parallel git snapshot download APIs feat(client): parallel git snapshot download with bounded in-memory streaming Jul 10, 2026
@worstell worstell force-pushed the worstell/parallel-get-stream branch from 084150b to 7d35e51 Compare July 10, 2026 23:48
…treaming

Download git snapshots with up to N concurrent range requests, reassembled
in order by a StreamSink and piped straight into zstd/tar extraction so
transfer and extraction overlap. Peak buffering is capped at
2*concurrency*chunkSize regardless of snapshot size: fetchers block once
they are a full window ahead of the consumer.

Chunks are pinned to the discovery ETag so a mid-download rewrite is
rejected rather than spliced; range-ignoring backends, missing ETags, and
small objects fall back to a single streaming request. Chunk fetches retry
transient per-replica failures, and extraction goes to a staging directory
renamed into place only on success.
@worstell worstell force-pushed the worstell/parallel-get-stream branch from 7d35e51 to 310ef7c Compare July 10, 2026 23:55
@worstell worstell marked this pull request as ready for review July 11, 2026 00:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 310ef7c416

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/cachew/git.go
return err
}

if err := os.Rename(staging, c.Directory); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve restores into populated target directories

When c.Directory already exists and contains files (for example rerunning cachew git restore ... ./repo over a previous checkout or a partially prepared workspace), this final rename fails with directory not empty instead of completing the restore. The old path extracted with snapshot.Extract(..., c.Directory, ...), which allowed that workflow; if staging is required, the existing tree needs to be removed/replaced intentionally or this should only take the rename path when the destination is absent.

Useful? React with 👍 / 👎.

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.

2 participants