Skip to content
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

Add context to storagedriver.(Filewriter).Commit() #4109

Merged
merged 1 commit into from Oct 19, 2023

Conversation

milosgajdos
Copy link
Member

@milosgajdos milosgajdos commented Oct 18, 2023

This PR changes storagedriver.Filewriter interface by adding context.Context as an argument to the Commit interface func.

We pass the context appropriately where need be throughout the distribution codebase to all the writers and tests.

In the case of the S3 storage driver we pass the context down to the driver writer and update all the AWS SDK calls in the writer with their WithContext variant. See this PR for more context (pun intended): #4066

PTAL @corhere, would love to get your thoughts/ideas on this.

@@ -1338,6 +1338,7 @@ func (b *buffer) Clear() {
// cleanly resumed in the future. This is violated if Close is called after less
// than a full chunk is written.
type writer struct {
ctx context.Context
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I know this is sad. Please read the whole thread in the discussion linked in the PR description. It's also why this PR is marked as a Draft. @corhere and I wanted to chat some things through and broken code is the best place to discuss them 😄

Copy link
Collaborator

Choose a reason for hiding this comment

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

That doesn't really explain it for me. Why have the context in the object instead of adding a ctx param to every method of writer that makes an s3 call?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because writer is created in S3 driver dynamically in the (driver).Writer() call

Now, it ten calls a bunch of AWS SDK funcs (that fire API reqs to AWS) that need to have context passed down to them from the upstream consumer so they can be called etc,.. The biggest problem is the Write method that must implement io.Writer:

And then there is also flush which also needs the upstream context because it makes upload finalising API calls and is called from the above-mentioned Write and from Close (which is there to implement io.Closer IIRC).

How else do imagine this should work?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't have a better solution, but I will need to read a little more code before I understand it enough to review confidently :)

Copy link
Member Author

Choose a reason for hiding this comment

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

SGTM. I hope you don't get too horrified by all that code 😁 No rush on this one

Copy link
Collaborator

Choose a reason for hiding this comment

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

Had a look, apologies for just pointing at generic doc instead of reading properly the first time.

I guess this is similar to solutions like https://pkg.go.dev/github.com/dolmen-go/contextio

One thing that could be a nice addition is a test that starts a writer and then cancels it to make sure we get back a context cancellation error, but that's not blocking for me.

@milosgajdos milosgajdos changed the title Pass the S3 storage driver context its writer Pass the S3 storage driver context to its writer Oct 18, 2023
@corhere corhere mentioned this pull request Oct 18, 2023
4 tasks
Copy link
Collaborator

@corhere corhere left a comment

Choose a reason for hiding this comment

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

Since v3.0.0 has not been tagged, we currently have a rare opportunity to make breaking API changes. While there is nothing we can do about the standard library io.WriteCloser interface, the driver.FileWriter interface is under our control. Now's our chance to add a context argument to (FileWriter).Commit()!

// Commit flushes all content written to this FileWriter and makes it
// available for future calls to StorageDriver.GetContent and
// StorageDriver.Reader.
Commit() error

I have spotted other candidate interfaces to be made more context-aware. But to avoid derailing this PR or expanding its scope too much, I have opened #4110 to host that discussion.

registry/storage/driver/s3-aws/s3.go Show resolved Hide resolved
@@ -1536,7 +1537,7 @@ func (w *writer) Cancel(ctx context.Context) error {
return fmt.Errorf("already committed")
}
w.cancelled = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

Aside: does this (and the other flags) need to be be changed to atomics—in its own PR, of course—so Cancel() is safe to be called concurrently with Write() and friends?

registry/storage/driver/s3-aws/s3.go Outdated Show resolved Hide resolved
@milosgajdos
Copy link
Member Author

milosgajdos commented Oct 18, 2023

This PR has got a bit chunkier. Thanks @corhere 🤣

I should probably rephrase the PR message now that we've taken a bit of a turn.

@milosgajdos milosgajdos changed the title Pass the S3 storage driver context to its writer Add context to storagedriver.(Filewriter).Commit() Oct 18, 2023
@milosgajdos milosgajdos marked this pull request as ready for review October 18, 2023 18:07
Copy link
Collaborator

@corhere corhere left a comment

Choose a reason for hiding this comment

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

LGTM!

if err := w.checkClosed(); err != nil {
return err
}
w.closed = true
ctx := context.TODO()
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's always nice to see TODOs melt away.

@@ -1338,6 +1338,7 @@ func (b *buffer) Clear() {
// cleanly resumed in the future. This is violated if Close is called after less
// than a full chunk is written.
type writer struct {
ctx context.Context
Copy link
Collaborator

Choose a reason for hiding this comment

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

Had a look, apologies for just pointing at generic doc instead of reading properly the first time.

I guess this is similar to solutions like https://pkg.go.dev/github.com/dolmen-go/contextio

One thing that could be a nice addition is a test that starts a writer and then cancels it to make sure we get back a context cancellation error, but that's not blocking for me.

@milosgajdos
Copy link
Member Author

I will squash the commits before merging if that's ok with you @Jamstah

There are some "broken" commits in this PR so would be good to squash them to a single one.

@Jamstah
Copy link
Collaborator

Jamstah commented Oct 19, 2023

Yes of course, squash away. And use a conventional commit ;)

This commit changes storagedriver.Filewriter interface
by adding context.Context as an argument to its Commit
func.

We pass the context appropriately where need be throughout
the distribution codebase to all the writers and tests.

S3 driver writer unfortunately must maintain the context
passed down to it from upstream so it contnues to
implement io.Writer and io.Closer interfaces which do not
allow accepting the context in any of their funcs.

Co-authored-by: Cory Snider <corhere@gmail.com>
Signed-off-by: Milos Gajdos <milosthegajdos@gmail.com>
@milosgajdos milosgajdos merged commit 5aee8e1 into distribution:main Oct 19, 2023
12 checks passed
@milosgajdos milosgajdos deleted the writer-context branch October 19, 2023 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants