Repository navigation
feat(storage): emit Storage.UploadChunk spans for gRPC appendable uploads - #20886
Draft
sahusneha2004 wants to merge 2 commits into
Draft
sahusneha2004 wants to merge 2 commits into
sahusneha2004 wants to merge 2 commits into
Conversation
…oads Record Storage.UploadChunk child spans for gRPC appendable object uploads (BidiWriteObject) when Writer.ChunkSize > 0, matching resumable uploads. Unfinalized appendable flush acks that return the object resource now confirm only Resource.Size bytes instead of completing all in-flight chunk spans, and a flush without data completes the open chunk span. [Generated-by: AI]
Contributor
There was a problem hiding this comment.
Code Review
This pull request adds tracing support for appendable uploads in the gRPC storage client, enabling the recording of Storage.UploadChunk spans which were previously only recorded for resumable uploads. It introduces tracking for appendable streams, handles empty flushes, and manages unfinalized object resource acknowledgments within the grpcUploadChunkTracker. Additionally, comprehensive unit tests have been added to verify these tracing behaviors. There are no review comments, so I have no feedback to provide.
Confirm Resource.Size bytes for every response that carries the object instead of detecting appendable streams from their first message, and document chunk numbering. Replace requestedChunkSize with chunkingRequested. Make the fake appendable server return the object with a write handle only in the first response and acknowledge later flushes with persisted_size, and add tests for held flush acks, empty and mid-chunk flushes, and an appendable retry. [Generated-by: AI]
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Emit
Storage.UploadChunkchild spans for gRPC appendable object uploads (BidiWriteObject) whenWriter.ChunkSize > 0, matching resumable uploads. This follows up on #20750, which excluded appendable uploads from chunk tracing.Addresses item 3 of b/581841769.
Changes
storage/grpc_writer.gopickBufferSendernow attaches the upload chunk size to the context on both appendable paths (new object and takeover), soattemptStatsHandlerinstalls agrpcUploadChunkTracker.chunkingRequestedfield (params.chunkSize > 0) records whether the application set a positiveChunkSize.w.chunkSizecan't be used because it is always at least 256 KiB.w.forceOneShotcan't be used either, becausegatherFirstBufferalso sets it for small objects. With this field,ChunkSize == 0stays untraced.storage/trace.go(grpcUploadChunkTracker)Resource.Sizebytes instead ofMaxInt64. This matchescompletion()ingrpc_writer.go. The size is the persisted size: every chunk once the object is finalized, or the bytes persisted so far for an unfinalized appendable object. So chunk spans still in flight are not ended early, for example by the object returned in the first response of an appendable stream. The tracker does not try to detect appendable streams from their first message; it trusts the size for every upload type.finish_writethat carries no data now marks the open chunk span as flushed. This coversWriter.Flush, orCloseafter all buffered data was already sent.offset/chunkSize + 1. A comment now explains that this is the 1-based index of thechunkSizewindow holding the chunk's first byte, so spans can share a number after a mid-chunkFlushor an unaligned takeover.gcp.storage.payload.offsettells them apart.Tests (
storage/trace_test.go)appendChunkTraceTestServeris a fake appendable server. The first response on each stream returns the object (size 0, or the takeover offset) with a write handle. Later flushes are acknowledged withpersisted_size, and finalizing returns the finalized object.TestAppendableWriterUploadChunkSpanschecks:ChunkSize == 0produces no spansUNAVAILABLEmid-upload: the in-flight chunk span ends with the error, and new OK spans with the same numbers are recorded on the next streamTestAppendableWriterUploadChunkSpansHeldAcks(new object and takeover) holds the flush acks while two or more chunks are in flight, after the first-response object has been received. It checks that no chunk span ends while acks are held, and that all end afterwards. It fails if the resource is treated asMaxInt64again (checked locally with that change applied).TestAppendableWriterUploadChunkSpansFlushchecks that an emptyWriter.Flushends the open chunk span beforeClose, and the numbering after a mid-chunk flush (256 KiB chunks; write 100 KiB, flush, write 300 KiB, close → numbers 1, 1, 2 at offsets 0, 102400, 364544).TestGRPCUploadChunkTrackerResourceAckchecks that a resource ack ends only the spans withinResource.Size: unfinalized mid-stream (new object and takeover), finalized appendable, resumable, and a resource that arrives before the first request.TestGRPCUploadChunkTrackerEmptyFlushchecks that a flush with no data ends the open span only once it is acknowledged.appendablecase ofTestWriterTraceWriteModeEmulatedchanged: it now expects one chunk span. This test needs the emulator and was not run locally.Validation (local):
gofmt -landgoimports -lreport no files.go build ./...andgo vet .pass.go test -race -short -count=3 -run 'UploadChunk|GRPCUploadChunkTracker|Appendable|PayloadTracing|AttemptStatsHandler' .passes.go test -race -short .instoragepasses.Merge only after the
kokorocheck is green on the head commit.Open questions (resolved)
offset/chunkSize + 1, as in resumable and HTTP uploads. This is now documented in the code. After a mid-chunkWriter.Flushor an unaligned takeover, spans can repeat a number; the offset attribute tells them apart. Repeats in flush-heavy workloads will be raised with the tracing spec owner.ChunkSize, a small appendable upload emits oneUploadChunkspan, because it still uses an upload session. A resumable upload of the same size becomes oneshot and is not traced.finish_writemarks the last span as flushed, so for resumable uploads the last span ends when the finalize ack arrives instead of when the stream ends. The timing is effectively the same.TagRPCand tracker, so chunk spans are deduplicated only within a stream.