-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Ambiguous rules for Isolate message (Illegal argument in isolate message) #38964
Comments
I'd guess that at a minimum, closures are not allowed. I'll let the VM team answer more generally. |
Can't I access the externalObject instance via a global variable or a static field? What is the point of this limitation? |
The VM currently only allows closures of top level methods or static methods in a class to be sent in isolate messages. This is currently not documented here https://api.dartlang.org/stable/2.6.0/dart-isolate/SendPort/send.html, we should improve that documentation. |
@a-siva |
Sending an object entails serializing all it's fields, you are sending object1 which is a Worker object, one of it's fields is externalReference which is of Type ExternalClass and one of the fields of ExternalClass is a closure (_internalClosure). |
Why serialize at all here? I might want to send a ByteBuffer with 100MB of data to an isolate. What will happen to it? |
@duzenko I have no idea why a static or top-level function is required. Maybe it provides some useful capabilities, but, in my case, it was completely useless and misleading. In order to avoid that error, I just made a top-level function that has an empty body. Let me know if this helped, if you have questions, or if you need further clarification. Here is an example of what I did:
|
I think your case is different. You need a completion notification but I want to send an object reference that has complicated links to other objects which leads to unwanted serialization error. |
@duzenko Hi, I had a somewhat similar issue. My workaround was to use good old class derivation. If you came up with another solution I would be happy to hear. Here's the code:
|
Documentation is still confusing: https://api.dart.dev/stable/2.6.0/dart-isolate/SendPort/send.html
So it works in only command line apps? Only in flutter's debug mode? Does it work in the browser?
So I guess flutter supports it fully, even o the web? Also, how this can work without reflection in AOT mode? |
As the comment states: it works everywhere where Dart VM is used. Which is in CLI and native Flutter applications irrespective of mode (debug, profile and release all use Dart VM). @mit-mit do we have some term to replace Dart VM in that comment. Should we rewrite it to say "Dart Native Runtime"?
Flutter Web is not a released thing - so documentation is not updated to reflect its limitations. Consider filing a bug on Flutter repo.
Similarly to how GC works - you don't need to know a lot of things (e.g. field names), you need to know just how many fields are there and which ones are pointers and which ones are primitives. |
Thanks for explanation, it makes sense now. I raised this topic because I've seen multiple people confused by this. I think this method requires a good detailed explanation, including what can't be copied, what's the performance of copying, in which environments Dart VM is not used (Is this only in regular Dart transpiled to js?), etc. |
Yes, I'd use the term 'Dart Native platform' as on https://dart.dev/platforms |
The comment referred to "dart vm" which confused users reading documentation. Use "Dart Native" instead and link to the page on the site describing it. R=lrn@google.com, mit@google.com Issue #38964 Change-Id: I50cf1b67d9e709d81a1ca7dced8da2f84488873e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161781 Reviewed-by: Lasse R.H. Nielsen <lrn@google.com> Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
@a-siva what if I want to send a http request or socket to a new isolate ? (for less computating time) |
@wustrong A http request or socket instance refers internally to a Since this issue is mainly about sending closures and better clarification of what can be sent, I'm going to merge it into the more general #46623. We plan on addressing the closure issue in the near future as part of that. |
I try to send
Any solution to that? |
The way I understand their design, anything CPU-intensive should be done in native platform code (except Web, where that must happen on backend), |
Ok, good to know. I suspected using Isolates for fetching data from websocket was an overkill. |
In general it's a fine solution to move background work (especially if it does some non trivial synchronous work) to helper isolates and send results back to the main isolate - this avoids having longer pause times or other work interrupting the UI. Though the helper isolate will have to make its own http client / websocket / ... (such resources cannot be sent across isolates) and the result message sent to the main isolate must not contain native resources either. This is explicitly mentioned in the documentation of SendPort.send:
|
For example? |
Many tasks can easily take up several milliseconds (utf8/json/protobuf decoding/encoding, ...). To maintain responsive UI the main isolate has < 16 ms to render a frame, so having too much synchronous work in there can cause drops in FPS. |
Last time I checked everything going in and out of isolate is force-converted to json. So decoding json in an isolate is guaranteed to be at least 2x slower than on main thread. Has anything changed there? |
There was never any conversion to json involved in inter-isolate messages. Though as part of #36097 we have made a number of improvements to isolates and the communication mechanisms. Using flutter's Using |
Is Flutter compute 'special' in that way? If yes, we should not discuss it and focus on dart isolates as this repo is general dart. If not, then how come the input data via |
Could you maybe file a new issue with example dart code you're having performance problems with? Then we can diagnose what happens and possibly make some improvements. (Hypothesising: If the input to |
Consider the following (originally flutter) code
It works as intended.
Now uncomment the line with the
_internalClosure
and now it throws an exception:What exactly rule does this code with a private closure breaks? Why is the message so ambiguous?
What classes can we and what can we not send into an isolate as a message? Where is it stated in the docs?
Note that the code above is the just a repro case. The real use case is much more complicated and took a significant effort to debug and analyze, as well as to create a repro case starting from a business flutter app.
The exception is thrown from the 'external' code that is already a head bump as it's not easy to see what condition fails. Where do I go looking for the source code for that part? Supposedly this is a dart VM?
The text was updated successfully, but these errors were encountered: