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

Introduce {bool exclusive = false} parameter to File.create({recursive}) method #49647

Closed
aam opened this issue Aug 11, 2022 · 22 comments
Closed
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. breaking-change-approved library-io type-enhancement A request for a change that isn't a bug

Comments

@aam
Copy link
Contributor

aam commented Aug 11, 2022

Desktop OSs allow for a file to be created in exclusive mode enabling simple concurrency-serializing mechanism.

from https://man7.org/linux/man-pages/man2/open.2.html

       O_EXCL Ensure that this call creates the file: if this flag is
              specified in conjunction with O_CREAT, and pathname
              already exists, then open() fails with the error EEXIST.

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen

EEXIST | _O_CREAT and _O_EXCL flags specified, but filename already exists.

This currently is not available for Dart apps.
This can be fixed via new optional exclusive parameter to https://api.flutter.dev/flutter/dart-io/File/create.html:

Future<File>> create(
{bool recursive = false,
bool exclusive = false}
)
@aam aam added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io type-enhancement A request for a change that isn't a bug labels Aug 11, 2022
@a-siva a-siva added the breaking-change-request This tracks requests for feedback on breaking changes label Aug 11, 2022
@a-siva
Copy link
Contributor

a-siva commented Aug 11, 2022

//cc @itsjustkevin

@itsjustkevin
Copy link
Contributor

Hey @aam please forgive my ignorance here, but is adding an additional parameter a breaking change if it has a default? There is usually a bit more context in these breaking change requests.

@aam
Copy link
Contributor Author

aam commented Aug 12, 2022

@itsjustkevin yeah, unfortunately even adding optional parameter with default value is a breaking change since it will break all the code that implemented that class - potentially internal code that is used in testing, code that provided mock implementation of File class. Code that implemented File class with its own implementation of Future<File> create({bool recursive = false}) now has to be changed to Future<File> create({bool recursive = false, recursive = false})

@itsjustkevin
Copy link
Contributor

Thanks for the breakdown @aam that was really helpful in understanding the scope of the change request!

Reaching out to @Hixie @grouma and @vsmenon to review this breaking change request.

@Hixie
Copy link
Contributor

Hixie commented Aug 12, 2022

We should add exclusive to package:file before we add it here, to reduce the impact of the breaking change. Other than that, SGTM. cc @tvolkert

@aam
Copy link
Contributor Author

aam commented Aug 12, 2022

We should add exclusive to package:file before we add it here,

Yeah, package:file is part of dart sdk build, so has to be addressed before File in dart:io dart sdk change can land.

@vsmenon
Copy link
Member

vsmenon commented Aug 16, 2022

We should study the breaking change impact, but lgtm.

@itsjustkevin itsjustkevin added breaking-change-approved and removed breaking-change-request This tracks requests for feedback on breaking changes labels Aug 16, 2022
aam added a commit to aam/file.dart that referenced this issue Aug 16, 2022
aam added a commit to aam/flutter that referenced this issue Aug 17, 2022
…ethod.

This is to soften landing of a breaking change dart-lang/sdk#49647
dnfield pushed a commit to dart-archive/file.dart that referenced this issue Aug 17, 2022
* Introduce stub of a exclusive parameter for File.create.

This is to soften landing of a breaking change dart-lang/sdk#49647

* Fix format

* Fix deprecated member use

* Update pubspec.yaml, CHANGELOG.md
@aam
Copy link
Contributor Author

aam commented Aug 17, 2022

Submitted cl/468267059 to soften landing in g3.

aam added a commit to flutter/flutter that referenced this issue Aug 17, 2022
…ethod (#109646)

* Introduce stubbed `exclusive` parameter to `File.create`-overridden method.

This is to soften landing of a breaking change dart-lang/sdk#49647
@rrousselGit
Copy link

rrousselGit commented Aug 18, 2022

👋 I'm not against the addition. I don't find the name very clear though

exclusive is a bit too broad IMO and doesn't look related to "does the file exist"

What about excludeExist? create(excludeExist: true) would be more explicit I think

@aam
Copy link
Contributor Author

aam commented Aug 18, 2022

exclusive was inspired by existing O_EXCL flag for open function in POSIX https://linux.die.net/man/3/open (that serves same function of having an open to fail when to-be-created already exists, and is actually used by the implementation).

@rrousselGit
Copy link

I understand that.
But I don't think someone could read create(exclusive: true) and understand its meaning unless they look at the documentation to know what exclusive does.

A name like excludeExist would still start with EXCL, so I think it would be a better compromise.

@aam
Copy link
Contributor Author

aam commented Aug 18, 2022

Thank you for your input @rrousselGit , getting to a consensus on naming can be hard as space is vast.
excludeExist doesn't sound right to me as we are not excluding anything - the operation has to fail if file already exist.

It seems natural to me to interpret notion of exclusive file creation to mean that we are the only ones who can create a given file.

cc @lrhn for more thoughts.

@rrousselGit
Copy link

It seems natural to me to interpret notion of exclusive file creation to mean that we are the only ones who can create a given file.

Personally, at first glance I thought "exclusive" would be related to access rights.
For example "The author of the file created has exclusive rights to that file".

Even after learning about what this flag does, I still fail to see the relation between the flag name and the behavior.

But English isn't my natural language. So if that's natural to others, ignore me 😊

@lrhn
Copy link
Member

lrhn commented Aug 19, 2022

Using the Posix flag name doesn't feel entirely right, because the API is not following the Posix structure otherwise (our open is not their open, we have create instead of open with O_CREAT.)

I see some possible alternatives:

  • Make a separate method, like createNew, instead of putting a flag on create.
  • Rename flag, say to mustNotExist or mustBeNew or newOnly. Not great names, I admit. Something shorter would be better, but new is a keyword.
  • Don't just fail if the file exists, allow the use to do something, adding {void Function(FileSystemEntity) ifExists} which, if provided and the file exists, so O_EXCL would made open fail), calls that function instead of creating the file. Basically, pass O_EXCL to open and if it fails, call ifExists. (Probably a little too speculative).

Not sure what users will want, though. It does feel mostly like it should be a flag on create, but naming is hard.

@aam
Copy link
Contributor Author

aam commented Aug 19, 2022

Thank you @lrhn . If I had to go for alternatives I would stay with the flag, yes, and pick mustBeNew as a name.
Given that exclusive was the one approved by folks and under way too, will ideally need one or more voices in next couple days to change from exclusive to mustBeNew.

@a-siva
Copy link
Contributor

a-siva commented Aug 19, 2022

Another option is change the orginal behavior of create which I feel was counter intuitive
The method was called 'create' which would mean create a file and I would have expected it to return an error 'file already exists' if the file already exists instead the current behavior just returns the currently existing file (did not do any creation).

@Hixie
Copy link
Contributor

Hixie commented Aug 19, 2022

My approval did not consider the actual name and semantics. I'm fine with whatever name or API approach is most idiomatic for Dart.

@aam
Copy link
Contributor Author

aam commented Aug 24, 2022

Given no more feedback on naming, going to submit the change as originally requested with exclusive optional parameter.

MaryaBelanger added a commit to MaryaBelanger/sdk that referenced this issue Sep 16, 2022
Line 86, dart-lang#49647 is missing a link to the issue
@MaryaBelanger
Copy link
Contributor

MaryaBelanger commented Oct 4, 2022

@aam Were the api docs updated? dart and flutter
Doesn't look like they are in production but I could be misunderstanding.
Nevermind, found it! https://dart-review.googlesource.com/c/sdk/+/255482/7/sdk/lib/io/file.dart#224

Edit: Is the practice here to wait until the change rolls out with the next stable to update the docs? Are the api docs changes in a CL somewhere, not linked to this issue?

@devoncarew
Copy link
Member

@aam - just to confirm - this change will be in 2.19.0 stable?

@aam
Copy link
Contributor Author

aam commented Nov 4, 2022

@devoncarew it's in latest beta(2.19.0-255.2.beta), so I assume yes.

@devoncarew
Copy link
Member

OK, for posterity, it looks like the first dev sdk with this change is 2.19.0-136.0.dev.

We are seeing some failures w/ this change; I opened https://github.com/google/file.dart/issues/204 to track them, but to paraphrase that issue, older versions of package:file fail when run on newer SDKs. We can't fix the underlying issue (retroactively adjust the supported sdk version range of the older package:file versions) but can likely mitigate things by publishing new versions of packages that use package:file.

devoncarew pushed a commit to dart-lang/tools that referenced this issue Oct 4, 2024
…ile#199)

* Introduce stub of a exclusive parameter for File.create.

This is to soften landing of a breaking change dart-lang/sdk#49647

* Fix format

* Fix deprecated member use

* Update pubspec.yaml, CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. breaking-change-approved library-io type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

9 participants