-
Notifications
You must be signed in to change notification settings - Fork 35
Option to specify context when creating file and location objects #282
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
base: main
Are you sure you want to change the base?
Conversation
funkyshu
left a comment
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.
I'm still thinking this through but I think the s3 example suggestions make sense.
| return nil, err | ||
| } | ||
|
|
||
| ctx := fs.ctx |
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.
Should this actually be on the FS? What happens when I do:
parent := context.Background()
ctx, cancel := context.WithCancel(ctx)
loc1, _ := s3fs.NewLocation(auth, somePath, WithContext(timer))
defer cancel()
todoCtx := context.TODO()
loc2, _ := s3fs.NewLocation(auth, otherPath, WithContext(todoCtx))Since todoCtx replaces, at least in the fs.context (which is always pass the to the GetClient) there really is no cancellation anymore. Same would happen with WithTimeout or some other value.
I kindof feel like there should be a NewFileSystem context option (no option default so context.Background()), that is used by any Location or File action that needs it, UNLESS we've specifically called NewLocation or NewFile with another context. So Location inherits ctx form FileSysetm and File (depending on where it NewFile was called (FileSystem or Location) inherits from its parent. However, any options passed to the "new" would override.
So filesystem.go is like:
func NewFilesyetm(some, args, ...opts) *FileSystem
// setup fs struct with default background ctx
fs := &FileSystem{
context = context.Background()
}
// apply option (would override with any provided context option)
...
return fs
}
func (fs *FileSytem) NewLocation(args, opts) *Location {
// setup Location with default **FileSystem** context
l := &Location{
context = fs.context
}
// apply option (would override with any provided context option)
...
return l
}
func (fs *FileSytem) NewFile(args, opts) *File {
// setup File with default **FileSystem** context
f := &File{
context = fs.context
}
// apply option (would override with any provided context option)
...
return f
}then in location.go:
func (l *Location) NewFile(args, opts) *File {
// setup File with default **Location** context
f := &File{
context = l.context
}
// apply option (would override with any provided context option)
...
return f
}In this way, any call to sub- struct initializers are independent of its parent when a new context is passed.
What do you think?
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.
I must be missing something because I've read your comment above a few times and I can't quite figure out what you're asking/suggesting. 😟
Context is only ever set in New* functions and never changed.
Files inherit the context of their parent FS/location unless overridden via newfile.WithContext.
Since todoCtx replaces, at least in the fs.context (which is always pass the to the GetClient) there really is no cancellation anymore.
It's true that in the s3 backend GetClient will always use the context of the root FS, however that's only used briefly when resolving the default AWS config. All client operations take a fresh context when used.
In your example, loc1 remains cancellable while loc2 is not.
You mention // apply option (would override with any provided context option) in the suggested code snippets, but isn't that what I'm already doing with the following code blocks?
ctx := l.ctx
for _, o := range opts {
switch o := o.(type) {
case *newfile.Context:
ctx = context.Context(o)
default:
}
}Apologies if I've misunderstood.
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.
I'll try to get back to this tomorrow.
eca9a4b to
3385e43
Compare
3385e43 to
c1a5761
Compare
Something I find lacking in this library is the ability to trace outbound requests. It's possible to configure instrumented clients for most backends but common tracing tools like OpenTelemetry use context to pass state around.
Rather than breaking every API by adding
context.Contextarguments (as previously discussed), I propose thegs.WithContextpattern be applied more widely toNewLocationandNewFile. This would allow a web application to have a single sharedFileSystem(orLocation) and inject the current request context when working with specific files.Here's a minimal example:
The other nice thing about this approach is it doesn't pollute the API for backends that don't support context, like
mem,osandsftp.This is a non-breaking additive change so in theory it could be included in
v7, but I understand if it needs to wait forv8.