-
Notifications
You must be signed in to change notification settings - Fork 19
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
What is a FileSystemHandle? #59
Comments
For the case of createWritable() on a FileSystemFileHandle that's been removed, Firefox currently fails the createWritable with NotFoundError, which seems reasonable (we created a FileBlob with a path that doesn't lead to a file -> NotFoundError). |
Open writables for us only lock the file, by the way. And with stable identifiers, move() of a file or directory doesn't actually cause a filesystem move, just a DB update. |
Note also that resolve() (or whatever we rename it to) is also impacted, of course. With a ref-based approach, resolve() would return the new path; with a pure path-based approach, it would return the original path (which may no longer refer to a file). With an invalidation-based approach, which the currently-written spec seems to take, it should probably throw. Invalidation would make all file/directoryhandles referring to or under a moved item become invalid, and would throw on most/all attempts to use them (but what about SyncAccessHandles? Thus your lock-on-parent-dirs approach I presume). Pure-path based would be visible in that given a handles to a, a/b, c and c/b, a->move(d) would make the make a/b invalid, but a subsequent c->move(a) would make the a/b handle valid again (and make c/b invalid). Invalidation would have that as never being valid again. With references, a->move(d) would make a/b into d/b. |
I prefer reference-based. It also simplifies thinking about SyncAccessHandles, since in a reference world, it's ok if an ancestor changes name, so there's no need to lock directories above it (and this would be the first idea of a directory lock here, which would be surprising to users). |
It seems in normal file system API, there will be two types of objects (classes): path and handle (entry, file descriptor), where path is stateless and handle is stateful. Path can be used for creating/deleting/renaming a file, and handle can be used to modify file content (e.g. c++ FileSystem library). I think the original design is However the existing spec seems to indicate |
If FileSystemHandle is a path, then the option to create the file/dir is odd and doesn't make sense; in that case the option to create should be on createSyncAccessHandle/createWritable. |
Resolving this issue blocks other work on the spec (and code/wpt's). Is there anyone else that needs to weigh in on this? Any other comments to resolve? |
I agree that this is the issue that we need to figure out first. Based on the discussion in #34 and other issues, I think we probably just want to mimic POSIX behavior and API. |
TLDR I'm supportive of the approach @szewai laid out and (barring any major concerns from @jesup) we can file other issues to bikeshed the specifics. Making a decision here would go a long way towards unblocking a number of other issues
+1 We looked quite hard into re-architecting around references, but outside of the OPFS this raises more questions than it solves and leads to behavioral inconsistencies that, frankly, I think would leave developers frustrated (e.g. say site A and B hold a handle to the same file. What happens to each site’s file handle if the file is moved… by site A? by another application on the machine? while the browser isn’t running? while a copy of the handle is stored in IndexedDB? if the site is registered for file change notifications WICG/file-system-access#72?). I know this spec isn't focused on the non-OPFS portion of the API, but a reference-based approach would certainly increase the effort needed to support even a subset of it (e.g. mozilla/standards-positions#738). And at the end of the day, it would be quite nice to be able to tell developers "a
Just to clarify, are you suggesting removing the Following the POSIX model, these are Adding the
|
I was thinking about adding it to
One issue about having create option on
It could be similar to
Yes, this is my first thought.
I am not sure I understand this. If we allow OPFS root directory to be removed, it seems fine to allow it to be recreated? |
I think this is desirable behavior? I can get behind adding a
SGTM 👍
I agree that it seems reasonable to allow re-creating an OPFS root - I just want to make we behave consistently in this case:
|
I just put up #96, which sketches out what specifying a path-based approach could look like. It's still very much a WIP, but gives an example (with Please feel free to leave feedback on that PR. Thanks! |
A much more thorough (than #30) attempt at expressing that FileSystemHandle maps to a file path. At a high level, it proposes that: * A FileSystemHandle has an associated "file system locator" * A "file system locator" contains, among other things, a "file system path" * A "file system entry" can be located given a "file system locator" * You can get a "file system locator" from a "file system entry" See #59 for the implications of this in practice. Fixes #59.
TPAC highlighted a pretty substantial architectural difference between the Chromium and Firefox implementations of this API. Chromium's implementation maps a
FileSystemHandle
to a file path (which I had attempted to codify a while back), while Firefox's implementation suggests "they are references to objects resolved at creation time."This has gone unnoticed until this point because no features have exposed this difference to the web.
But there are some significant web-observable implications to this choice, most notably around directory moves. Consider the following code, which moves a directory containing a child we have a handle to:
What happens next?
Directory moves very blatantly expose this difference. It will be basically impossible to specify directory moves in a way that's consistent across platforms without being much more specific here. This also has implications for at least the
getUniqueId()
method and removed handles. Directory moves would also expose a difference inresolve()
and a discussed-but-not-yet-formally-proposedgetParent()
method, among other things.Looking at the code above, I tend to agree that a ref-based approach leads to outcomes which are more likely to align with user expectations, at least regarding directory moves. It would be nice if moving a directory didn't invalidate all child handles, for example. Meanwhile, there are some instances where a path-based approach arguably makes more sense. What happens to a
FileSystemHandle
when its underlying file is removed?That being said, it seems reasonable to specify that a handle can still be written to if it's removed via this API, while handles removed by other means (such as by clearing site data or via an OS file manager) could be invalidated.
In summary...
One option is to never specify features that expose this implementation difference, such as directory moves. Unfortunately this is a pretty fundamental difference which I suspect will be hard to paper over as the API continues to evolve. To me, this is a very unsatisfying option. Consider a web IDE which just wants to rename
src/foo/
tosrc/bar/
, but is forced to recursively copy all contained files.Another theoretical option is to accept that there will be cross-browser differences. Sure, moving a directory will invalidate all child handles, but you can re-acquire all the handles within the new directory. However, going down this path is bound to expose many more subtle cross-browser differences. For example, Chromium locks all ancestor directories when a file has an open writable to ensure its path does not change while it is being written to. Having an open writable will block moving a parent directory, which would be a confusing restriction in a reference-based design. This option would be bad for developers and the impacted users, but just listing it here for completeness.
The other option is to specify a requirement that a
FileSystemHande
is a reference (in the same way I had attempted to specify it’s a path here). That framework could be used to specify new methods such asmove()
,remove()
andgetUniqueId()
in a way that’s consistent across browsers. This is our preferred option, but supporting this in Chromium would require a pretty substantial re-architecture that I'm hesitant to commit to without clear indication from other browsers and the developer community that handles should be based on references rather than paths...@szewai does WebKit have an opinion here?
The text was updated successfully, but these errors were encountered: