Skip to content

feat(mapper): add wire-size-based chunking and ResultToGetTargetGraphResponse#206

Closed
yushan8 wants to merge 6 commits into
yushan/remove-undocumented-config-fieldsfrom
yushan/mapper-chunk-methods
Closed

feat(mapper): add wire-size-based chunking and ResultToGetTargetGraphResponse#206
yushan8 wants to merge 6 commits into
yushan/remove-undocumented-config-fieldsfrom
yushan/mapper-chunk-methods

Conversation

@yushan8

@yushan8 yushan8 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Introduces wire-size-based chunking and a proto-free domain type for target graphs, separating entity conversion from proto serialization.

  • Add entity.OptimizedTarget and entity.TargetGraph as proto-free domain types for target graph data.
  • Add ResultToTargetGraph: converts targethasher.Resultentity.TargetGraph (proto-free, suitable for orchestrator use).
  • Add TargetGraphToProto: converts entity.TargetGraph → chunked []*tangopb.GetTargetGraphResponse (proto serialization + ID mapping + chunking).
  • Add internal/mapper/chunk.go with BySize (generic proto chunker bounded by real serialized size via Size()) and ChunkMetadata (map splitter by measured entry wire size).
  • BySize always returns at least one chunk (empty input → single empty chunk); non-first empty chunks return an error.
  • Both old (core/common) and new (internal/mapper) implementations coexist — callsite migration follows in config: bound stream chunks by real message size, not estimated #203.

This split enables a future PR to have the orchestrator work with entity.TargetGraph directly, removing proto from the orchestrator layer entirely.

Test plan

  • make build
  • make testResultToTargetGraph (entity conversion), TargetGraphToProto (empty graph), ResultToGetTargetGraphResponse (chunking at various sizes), BySize / ChunkMetadata unit tests
  • make gazelle && gofmt -w . && goimports -w .

Stack

  1. [config] Tango configuration documentation #180
  2. config: update fields, defaults, and required checks to match README #190
  3. config: remove fields not documented in config/README.md #191
  4. @ feat(mapper): add wire-size-based chunking and ResultToGetTargetGraphResponse #206
  5. config: bound stream chunks by real message size, not estimated #203

…Response

Introduce internal/mapper/chunk.go with BySize (generic proto chunker
bounded by real serialized size) and ChunkMetadata (map splitter).
Add ResultToGetTargetGraphResponse to internal/mapper/target_graph.go,
converting a targethasher.Result into chunked stream responses.

Both old (core/common) and new (internal/mapper) implementations
coexist — callsite migration follows in a subsequent PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yushan8
yushan8 requested review from a team as code owners July 15, 2026 17:59
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Comment thread internal/mapper/target_graph.go Outdated
// ResultToGetTargetGraphResponse converts a targethasher.Result into chunked
// GetTargetGraphResponse messages ready for streaming or storage. Each message
// is bounded by maxMessageBytes of real wire size (see chunkTargets).
func ResultToGetTargetGraphResponse(ctx context.Context, result targethasher.Result, maxMessageBytes int) ([]*tangopb.GetTargetGraphResponse, error) {

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.

I feel like this function is doing a lot of logic that maybe shouldn't be in mapper. This could be broken into two. First is taking targethasher.Result and processing it into optimized targets. This part can stay in orchestrator (optimized target needs an entity). Second is turning optimized targets into the proto response, so the mapper can do just this part.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes good point. Going to close this in favor of #211 to split it up better.

yushan8 and others added 4 commits July 15, 2026 21:19
…d proto steps

Add entity.OptimizedTarget and entity.TargetGraph as proto-free domain
types for target graphs.

Split the monolithic ResultToGetTargetGraphResponse into:
- ResultToTargetGraph: targethasher.Result → entity.TargetGraph (proto-free)
- TargetGraphToProto: entity.TargetGraph → chunked proto responses

This lets the orchestrator work with entity types while keeping proto
conversion confined to the mapper and controller layers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…unction

Callers should use the two-step flow (ResultToTargetGraph then
TargetGraphToProto) directly, keeping entity and proto concerns
explicitly separate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add entity.IDTarget, entity.GraphMetadata, and entity.GraphChunk as
compact ID-mapped representations for streaming and storage, mirroring
the proto shape without proto dependencies.

Add TargetGraphToChunks (entity.TargetGraph → []entity.GraphChunk),
GraphChunkToProto/ProtoToGraphChunk converters. TargetGraphToProto now
composes TargetGraphToChunks + GraphChunkToProto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Move streaming-split logic from internal/mapper/chunk.go to
internal/streaming/streaming.go with clearer names:
- BySize → streaming.SplitBySize (generic, proto-free)
- ChunkMetadata → streaming.SplitMetadata (returns entity.GraphMetadata)

The streaming package has no proto dependency — it works with the Sizer
interface and entity types only. Proto conversion stays in the mapper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@yushan8
yushan8 marked this pull request as draft July 16, 2026 22:12
@yushan8 yushan8 closed this Jul 17, 2026
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