-
Notifications
You must be signed in to change notification settings - Fork 1.7k
.packages: Ability to pass packages config data into Isolate.spawnUri #23951
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
Comments
Since this is changing the API of the Isolate.spawnUri and the plumbing of this into the VM loading code will be complicated, it is highly not likely to land in 1.12 for the VM implementation. As the VM is the only implementation where this feature really matters, I suggest to move the milestone to reflect reality. |
Thanks for the update. @nex3 what would be the impact if this doesn't land for 1.12 ? |
I'm fine if this doesn't make it into 1.12. I just wanted to make sure it was being tracked as part of #23372. |
Oh, I thought of one case where this will be necessary: we will need this before we can do dart-lang/pub#1204, which is something I'd like to see done by 1.13. |
Let's push hard to get this in by 1.13. |
We should do this, and the parameter should be |
Thanks @lrhn . Looking forward to it. |
This may also be useful, but it's not sufficient. We need to be able to pass in URIs to the files generated by pub; it would be a problem if everyone had to read them into memory and parse them before using them to spawn an isolate. |
I'm not sure I understand the objection - is the problem that you don't want to read in the ".packages" files generated by pub? If so, I don't think that will be a problem - we have a package for doing that. We can even extend that package with ways to run Dart scripts directly, something like: Future<Isolate> runScript(Uri script, [List<String> arguments, Object parameter]); which will use the correct search protocol to look for In other words, I think the problem can be handled by a package without extending the core Isolate.spawnUri API. |
Why wouldn't you want to pass in a URI? That API is simpler, it's consistent with |
I don't have any real-world examples. I do think that using a pre-existing Dart application is a somewhat common usage, and we should support it. In that case, you shouldn't even pass a URI, you should just say "run as application/script" and it will find the ".packages" file itself. I'd make a third That leaves spawnUri for the case where you have found the packages computationally. In that case it's an overhead to create a file and let the system read it back in, so a map from package name to location Uri is the best internal representation. So, I'm against passing a URI because it's either too much or too little for the usages that I actually predict. |
I believe this is because, in practice, there isn't Dart code that's interested in spawning isolates using a package spec that's generated from whole cloth.
This would also be useful, but it doesn't address a lot of the code that's actually using isolates in practice. A common use case is to spawn a script that isn't located in the current package using the current package's dependencies. Both
We don't have to predict or guess how people will use Isolates. We know how people use Isolates, because they're using them today. I use them all the time. And I'm saying it's important for actual practical use-cases to be able to spawn an isolate for code in an arbitrary location using an on-disk |
If we have only one parameter for specifying the package resolution, then it should be the most general one. That is the map parameter. With that, the other use-cases can be implemented by a package that we already have, either direclty in package_config, or possibly in the isolate package using package_config. |
Both parameters are expressively equivalent. Just like you can parse a package spec on disk into a map in memory, you can serialize a map in memory into a spec on disk. Given this equivalence, we should choose the parameter that satisfies all the known practical use-cases easily and efficiently. |
Natalie, your second statement is incorrect on a read-only file system. As Lasse mentioned, one can be built using the other, but not the other way around. |
Presumably |
Since this is new, we have exactly one real-world use. We should not generalize from one sample. We should use the same guiding principles that we have used in existing API design. For spawnUri we have added parameters to match command-line switches, but we have used meaningful Dart representations of the data instead of mirroring the command line's flat string structure. That's why the arguments is a List, not a single string which would be split on spaces, and the package-root is a Uri, not a String. For the same reason, the package-spec should be a Dart mapping from package name to package base URI, not the string contents of a file or the path to a file - those are not first-class Dart values for the data. And as Ivan points out, if you can write a file, then you can also read the file and parse it (and we already have code to do that), but if you have the data, you can't necessarily write a file. The structured-Dart-data parameter is the most general type. |
Isolates aren't new, and packages aren't new. It's been possible (with a little work) to start an isolate with a set of packages generated on the fly for more or less the entire public lifetime of the Dart project and no one has done so, despite a number of different applications using Isolates. Package specs don't bring any new expressive power to the table here.
A string versus an argument list is a small difference in representation—and anyway, the executable itself receive the arguments as a list from the shell. A URI versus a manually-parsed file is a huge difference in terms of user effort, affecting their dependency tree and the speed of their program.
We consistently support |
Hello, who is looking at this for 1.13? |
Out for review: https://codereview.chromium.org/1403693002/ |
Landed with 60eab65 |
It seems that this was closed without really solving the use case. I'd like to see this reopened with more discussion with the stakeholders. |
There are plenty of suggestions on how to solve the use-case (in particular, anything that has a package mapping in a file can read that file using |
@lrhn How do you find the package mapping? Also, how do you pass the package mapping to dart2js or any other command-line tool? |
@peter-ahe-google, have you seen the resource package? https://codereview.chromium.org/1387163002/ |
@peter-ahe-google To pass a mapping on the commend line to dart2js, you need to have a file. If you don't know of one that contains what you need, you can write one and use that. We have tools to help with that. |
@lrhn I'm looking for the name of the file that was passed to the Dart VM. For example, let's say I have these two programs: package_root.dart:
my_test_program.dart:
How do I convert this to use packages files? |
@peter-ahe-google That requires the yet-to-be-committed
But this is digressing - this issue was about providing a package mapping to |
This isn't digressing. You're claiming that you have solved all use cases by adding support for taking a Map but not provided support for passing a file name. In addition, you've chose to use the name "packageMap" to mean a Map<String,Uri> in Isolate.spawnUri, and apparently Platform.packageMap is going to be a String. This brings us to the questions of how do you get the package map in an isolate that has been spawned with spawnUri and a package map. Perhaps you intend to use data URLs for that, and that may work. But in that case Platform.packageMap should return a URI. I think there's a mismatch between how you specify packages to to Isolate.spawnUri and to a command-line tool, and there seems to be no compelling reason for this mismatch. |
I claim to have solved one use-case: Starting a new isolate with a different package resolution than the spawning isolate with a per-package mapping instead of a single package root (which we already had). The naming is Getting the package map of an isolate that has been created using Platform.packageMap/packagesFlag/whatever returns a String. It is the value of the There is a mismatch between how you provide structured data to a programming API and a command line because a command line is a horrible API for structured data. That's why we put the data in a file, so the first package mapping can be read from there. When you are writing Dart code, and staying inside Dart, you can use a Map, which is, in my opinion, a suitable level of abstraction. We should not lower ourselves to what fits on a command line when creating APIs. Getting from a map to a .packages file is a matter of serializing the map and writing it to a file, then you can have a URI pointing to that file if you need that for starting a command line tool. We have a package that can help you doing that. |
I think that this API is unnecessarily complicated due to the addition of Maps, and I'm having a hard time seeing how this adds value to dart2js which won't be able to support it. However, I can now see how my use cases are solved: I use Isolate.packageMap if I want to call Isolate.spawnUri using the same packages config as the current VM. I use Platform.packageMap (or whatever it is called) for external processes. I'm simply out of luck if I modify the packageMap and pass it to Isolate.spawnUri and try to use Platform.packageMap in the new isolate. But as luck would have it, I don't plan to do so. I'll just keep my fingers crossed that nobody decides to make Platform.packageMap return null in isolates that have been spawned using spawnUri. |
We had to pass a mapping to You can easily start a new Isolate with the same package resolution as the current Isolate (but then, you never needed a parameter for that, that is the default), and you can start a new process with the same command line arguments as this process. If you want to take the resolution of the current isolate (basically a kind of reflection), modify it, and then provide that as a command line parameter, then, yes, you need to create a new file - just as you would if you wanted any other new mapping that there is no file for. That's not really surprising. The only remaining case is to spawn a new isolate with a package mapping that currently exists in a file. You will have to convert that file to a map instead of just pointing to it. We have helper functions that can do that for you, so instead of perhaps writing |
A simpler solution than having two parameters would be to only have on parameter: a file name which gives you the location of a .pacakges file. The indirection you talk about is an implementation detail, and not a convincing argument for requiring people to use another package. It also leaves the semantics of Platform.packageMap (or whatever it's called) somewhat problematic in a spawned isolate. |
This is a serious amount of extra effort for very little added value. Not only is it vastly less common to want to do dynamically-generated package resolution, it's a lot easier and more reliable to create a data URI than it is to read a file from disk. The current API optimizes for the wrong use-case. The current API also gets in the way of solving #24524. If the creator of an isolate knows the location of the package spec file, it should be easy for code in the isolate to re-use that file. If we pass in a map, we're just dropping that information on the floor.
As one of the primary customers and the person charged with ensuring that users can continue to run their applications successfully using |
I just realized another problem with using a Map. Currently, the type of packageMap in Isolate is:
This means that we'll be hard pressed if we decide to add more features to the package configuration in the future. This would be equivalent to defining an isolate like this:
And then later realize that we want top-level methods. For this reason, the type of packageMap should be an identifier (a URI) or an opaque object (PackageConfiguration). Here's a couple of things that would be hard to add while maintaining the map interface:
Regardless of your opinion of these various features, you need to provide a future-proof API. |
Creating a future-proof API does not happen overnight. @mit-mit : We should drop this from 1.13. |
I believe this has landed |
To support the new
.packages
file and issue #23369 , we would like to ask if we can pass the data from that file intoIsolate.spawnUri
. Currently,Isolate.spawnUri
takes a named parameter forpackageRoot
.The text was updated successfully, but these errors were encountered: