-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chunked: rework GetBlobAt usage #2162
chunked: rework GetBlobAt usage #2162
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: giuseppe The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
c782691
to
e2cd1d2
Compare
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
testing in containers/podman#24478 |
e2cd1d2
to
4656a32
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Just a quick look for now — this looks like the right approach in general.
@@ -48,21 +48,21 @@ func readEstargzChunkedManifest(blobStream ImageSourceSeekable, blobSize int64, | |||
Offset: uint64(blobSize - footerSize), | |||
Length: uint64(footerSize), | |||
} | |||
parts, errs, err := blobStream.GetBlobAt([]ImageSourceChunk{chunk}) | |||
|
|||
footer := make([]byte, footerSize) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, a lot of the code could benefit from a single “ask for one chunk, read it into memory, validate against a digest” utility.
Arguably that’s a cleanup that should not block this PR…
if err != nil { | ||
return nil, nil, nil, 0, err | ||
} | ||
|
||
defer func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works.
Maybe another way to structure the consumers would be to:
defer consumeRemainingStreamsOrErrors(streamsOrErrors) // this loop, ignoring all errors. Also see elsewhere — maybe this should be a context cancellation instead.
// consume data: if there is only one chunk:
reader, err := getNextStream(streamsOrErrors) // if this contains an error, or is closed, returns an error
// Optionally, after all data is consumed: Alternatively, this can be enforced in `getBlobAt` — if we are fine with ignoring errors after all expected data is consumed, like excess chunks.
err := ensureAllDone(streamsOrErrors) // Ensure straemsOrErrors is at EOF, there are no unexpected items, there are no errors reported .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking more into this, I don't think we should ignore errors. I'll move the code to a new function
if err != nil { | ||
return nil, nil, nil, 0, err | ||
} | ||
|
||
defer func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to consume everything is, generally, an undesired cost.
The typical handling for that is to use a cancellable context, and to have the consumer here defer cancelTheContext
; and for the goroutine to observe that context and terminate on cancellation.
Sadly that is not possible in ImageSourceSeekable
(no Context
parameter), but maybe we could build the streamsOrErrors
the idiomatic way, and have getBlobAt
deal with draining the produced output, instead of doing that in every consumer.
(I didn’t try, this might be too hard to do. Notably channel sends in getBlobAt
would also have to select
vs. the context terminating.)
4656a32
to
5e80346
Compare
5e80346
to
ea81dba
Compare
@cgwalters thanks for the review. Addressed the comments and pushed a new version |
ea81dba
to
d8f279c
Compare
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK overall, and the tests are great.
d8f279c
to
e1238b6
Compare
@mtrmac addressed your comments, pushed a new version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code LGTM. Can I ask for one last test change?
e1238b6
to
8ae71aa
Compare
what do you think of the last version? |
Sure, that works. The |
rewrite how the result from GetBlobAt is used, to make sure 1) that the streams are always closed, and 2) that any error is processed. Closes: https://issues.redhat.com/browse/OCPBUGS-43968 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
8ae71aa
to
1f54749
Compare
/lgtm |
@giuseppe Thanks! |
rewrite how the result from GetBlobAt is used, to make sure 1) that the streams are always closed, and 2) that any error is processed.
Closes: https://issues.redhat.com/browse/OCPBUGS-43968