go-webdav icon indicating copy to clipboard operation
go-webdav copied to clipboard

FileSystem interface: provide context, make FileInfo an interface

Open fstanis opened this issue 5 years ago • 5 comments
trafficstars

Just a suggestion: I was looking to potentially use this project instead of golang.org/x/net/webdav and noticed the FileSystem interface is slightly different:

  1. go-webdav doesn't pass a Context to its calls.
  2. FileInfo is a struct and not an interface.
  3. Readdir returns a []FileInfo (slice of values) but Stat returns a *FileInfo (pointer).

I was wondering if you'd consider changing this in the future? Specifically, the first two are useful for when a file system is actually remote like e.g. Dropbox or Google Drive. And using pointers in the slice is just good for consistency (and also, deep copying a slice of values has a larger overhead).

fstanis avatar May 09 '20 16:05 fstanis

go-webdav doesn't pass a Context to its calls.

Yeah, context support is probably desirable.

FileInfo is a struct and not an interface.

FileInfo is just a metadata container, why would it need to be an interface?

Readdir returns a []FileInfo (slice of values) but Stat returns a *FileInfo (pointer).

Using pointers in slices is worse in this case, because each FileInfo needs to be allocated separately and the GC needs to keep track of each pointer.

emersion avatar May 09 '20 16:05 emersion

FileInfo is just a metadata container, why would it need to be an interface?

For example, for Google Drive it's convenient to keep additional information, such as an ID. Using an interface means I can reuse the same internal structure, as opposed to making a copy to be compatible with go-webdav. An interface also gives a guarantee that go-webdav doesn't mutate the structs.

I agree on the GC overhead for a slice of points, but this may be premature optimization. Specifically, I'm worried that many file system implementations would keep a cache of FileInfo objects somewhere in a different structure (e.g. a tree) and would then need to construct a slice when Readdir is called, effectively copying a lot of data. With pointers, there would only be slice construction overhead, the underlying data wouldn't be copied.

fstanis avatar May 09 '20 16:05 fstanis

See also: https://go.googlesource.com/proposal/+/master/design/draft-iofs.md

emersion avatar Jul 21 '20 22:07 emersion

The io/fs package has been merged: https://tip.golang.org/pkg/io/fs/

emersion avatar Nov 11 '20 09:11 emersion

context has been plumbed through now.

For example, for Google Drive it's convenient to keep additional information, such as an ID. Using an interface means I can reuse the same internal structure, as opposed to making a copy to be compatible with go-webdav. An interface also gives a guarantee that go-webdav doesn't mutate the structs.

This doesn't really help, a slice of []*customFileInfo can't be cast directly to a []webdav.FileInfo when webdav.FileInfo is an interface. Some amount of copying is required either way, and I don't think filling the webdav struct is that much work.

emersion avatar Jan 18 '24 12:01 emersion