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

Unable receive Platform Channel calls in background isolates #119207

Open
lukaszciastko-spica opened this issue Jan 26, 2023 · 21 comments
Open

Unable receive Platform Channel calls in background isolates #119207

lukaszciastko-spica opened this issue Jan 26, 2023 · 21 comments
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter engine flutter/engine repository. See also e: labels. P3 Issues that are less important to the Flutter project team-engine Owned by Engine team triaged-engine Triaged by Engine team

Comments

@lukaszciastko-spica
Copy link

Please, enable full support for Platform Channels from any Isolate.

I'm really confused why this issue has been closed as this hasn't been fully solved and currently it's only possible to achieve a one-way communication with the native code from any Isolate.

When i try to call an Event Channel inside another Isolate, I'm getting the following error:

Unsupported operation: Background isolates do not support setMessageHandler(). Messages from the host platform always go to the root isolate.

A possible use case for Event Channels is observing a collection of Firestore documents to perform a computation on the data or observing a user's location.

@stuartmorgan
Copy link
Contributor

I'm really confused why this issue has been closed as this hasn't been fully solved

It's closed because the request was to be able to call platform channel method from background isolates, and that was implemented. What you are asking for here is the opposite, which is a different feature.

@gaaclarke I know this was a known area of potential future work; is there an issue tracking it already, or should we use this one?

@stuartmorgan stuartmorgan changed the title Unable to use Platform Channels from another Isolate Unable receive Platform Channel calls in background isolates Jan 26, 2023
@gaaclarke
Copy link
Member

gaaclarke commented Jan 26, 2023

I haven't seen one. This feature was originally in the design doc but I ended up not implementing it since there was some disagreement about it (and not what was technically asked for). Creating an issue that lists a clear use-case voiced from a customer can help prioritize that discussion.

@stuartmorgan stuartmorgan added c: new feature Nothing broken; request for a new capability engine flutter/engine repository. See also e: labels. labels Jan 26, 2023
@lukaszciastko-spica
Copy link
Author

It's closed because the request was to be able to call platform channel method from background isolates, and that was implemented. What you are asking for here is the opposite, which is a different feature.

I understand, but I also think that people might have assumed that this would be implemented both ways. At least I did, and I saw some comments on the web people trying this and failing.

I struggle a lot with Firestore. Trying to get a few dozens of objects across from Android to Flutter always jams the UI thread. And if a single object changes, the whole collection is going through the channel again and again. As a temporary solution, I create multiple listeners and try not to observe more than 30 or so documents at a time, but this isn't ideal.

Isolates are perfect for long-running tasks, and this might often involve listening to a stream of data.

@dayoul
Copy link

dayoul commented Jan 30, 2023

Hello @gaaclarke, I've seen in the official doc about this feature

Plugins and channels can be used by any Isolate, but that Isolate has to be a root Isolate (the one created by Flutter) or registered as a background Isolate for a root Isolate.

but it's still not working like @lukaszciastko-spica mentioned.
Which opinion is correct?

@chinmaygarde chinmaygarde added c: proposal A detailed proposal for a change to Flutter P3 Issues that are less important to the Flutter project labels Jan 30, 2023
@knaeckeKami
Copy link
Contributor

@gaaclarke for a use case, here an issue that I opened in http: dart-lang/http#876

  • http added experimental packages for accessing native http features of Android and iOS in order to leverage platform features like automatic proxy detection and captive WiFI support
  • cupertino_http uses ffi, so it works properly in all isolates
  • cronet_http, the android implementation, uses platform channels and setMessageHandler(), which is why it only runs in the main isolate

It is pretty common, however, to run networking logic in a different isolate in order to not block the UI while parsing JSON.
Which can be challenging to implement when the calls have to be initiated on the main isolate.

@atrope
Copy link
Member

atrope commented Mar 3, 2023

I've tried to use http in an isolate without success (and without error messages 🤣 ) and then i found out this thread 😬 +1 that we should be able to use cronet_http in Isolates.

@atrope
Copy link
Member

atrope commented May 24, 2023

Hello all, shouldn't we prioritize this issue so we can make http calls and work in isolates?

@SmallCharm

This comment was marked as off-topic.

@vadimbarda

This comment was marked as off-topic.

@raspberry-jenshen

This comment was marked as off-topic.

@atrope
Copy link
Member

atrope commented Dec 7, 2023

Hello all, shouldn't we prioritize this issue so we can make http calls and work in isolates?

I can confirm the new version of cronet_http is working in Isolate

@Ahmadre
Copy link

Ahmadre commented Dec 12, 2023

@gaaclarke @stuartmorgan
Wanted to file a customer based use case where we need exactly this:

We have lung-patients in our customers clinics where they need to fill out questionnaire's with which doctors immediatly update their treatment according to the results of those survey-reports. But in some areas they don't have any cellular or wifi connection to save those survey's. That's why I am using a package which implements background isolates which executes code in background to get cached survey results and try to upload them in the background. This is necessary so doctor's get as fast as possible those results and can update their patient's treatment!

We have a workaround where patients needs to open their app and the app checks for last survey's which tried to upload them and when an internet connection is re-appearing the app will upload them in foreground.

So it would be great to fullfill this important feature in our app, when this issue is fixed/implemented.

@Ortes
Copy link

Ortes commented Jan 6, 2024

My usecase is create a pedometer like app it needs to receive the sensors event when the app is not in the foreground and the screen is locked.
For workaround I use it the the main thread and it seems that the messages are not lost and are received when the app is in the foreground again but this is not a realistic solution.

@BuzzBumbleBee
Copy link

This seems to also affect Bluetooth Low Energy packages such as flutter_blue_plus, see :
https://github.com/boskokg/flutter_blue_plus/blob/master/lib/src/flutter_blue_plus.dart#L383

I am guessing as the platform code needs to call back to the running dart code asynchronously in a few scenarios (such as)

Not being able to run this outside of the main Isolate would be a limitation if you end in a situation when a lot of IO is happening over Bluetooth, for me I am trying to read live data as quickly as possible from a BLE connected device without locking the UI thread.

@BuzzBumbleBee
Copy link

BuzzBumbleBee commented Jan 14, 2024

I have a very WIP solution for this, here :

BuzzBumbleBee/engine@add89fd

This allows you to register a callback within the platform message handler for a specific channel,

This callback is a simple mapping of a send port to a channel name.

When the platform code tries to invoke dart code and this callback is available the message will be passed to the background isolate binary messenger via the send port

Could someone advise on if this concept would be something that could be adopted? (I'm happy to cleanup the MR ... Tested / docs etc but would like to know if I'm on the right track)

@gnprice
Copy link
Member

gnprice commented Mar 28, 2024

Following up on the above: it looks like @BuzzBumbleBee began a design doc for this feature:
https://docs.google.com/document/d/1ebFrip3jv9xMAL8VdhIS_88wiI13XeH4QajOBBIeaQM/edit

As I read the discussion there, the main open question is what the API would look like for arranging to receive these calls in a given isolate.

In particular, in a typical scenario, a platform channel belongs to some plugin as an internal implementation detail, but it's the application that wants to decide there should be a background isolate and decide what calls should be received there. So there needs to be some picture of how the application code would communicate that choice, either as a proposed API the application would use directly or by having some picture of what API a plugin might provide for an application to do so (along with a proposed API for the plugin to then use).

@BuzzBumbleBee
Copy link

@gnprice yeah unfortunately I ran out of time and was unable to articulate things in the timeframe I had.

My initial MR is still about, and would happily pick it up again. Just may need a bit of an assist on the documentation of the API, IMO ideally it would be transparent to the plugin dev (the plugin shouldn't care if it was registered on the main isolate or background).

@tomekit
Copy link

tomekit commented May 21, 2024

I am not sure how it's going with this Feature Request, however I've thought I would share an additional real world use case.

At the moment there is no reliable way to get the native Android file (via Content URI) as a stream for further processing.

This library: https://pub.dev/packages/uri_to_file can do it, but it would COPY file and then expose it as a filepath to Flutter, which isn't feasible for big files of if there isn't enough space on the user's device.

There is a rather new library: https://pub.dev/packages/uri_content which translates native Android ContentURI using Platform Channels to Dart stream which is extremely useful.

Unfortunately if you use it from the background isolate it won't work due to current limitation also mentioned here: talesbarreto/uri_content#10

It would be really great if Flutter could receive data from Platform Channel inside of a background isolate.

Before this gets implemented there is really no feasible way to process big files using Flutter which is somewhat limiting.

@BuzzBumbleBee
Copy link

@tomekit I'm still intending to rework the MR, hopefully I'll get around to it in the next few weeks if no one has picked it up beforehand

@BuzzBumbleBee
Copy link

@gnprice would it be possible to get a call of some kind setup to define / agree on the API ?

Im happy to then refactor my changes to follow that API

@stuartmorgan
Copy link
Contributor

@BuzzBumbleBee The next step here would be to update the design document. Currently there's a comment thread where I explained that what is proposed there isn't something we would move forward with; you referenced another idea there but haven't updated the document to reflect it so there's nothing specific enough to discuss in detail, much less agree on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter engine flutter/engine repository. See also e: labels. P3 Issues that are less important to the Flutter project team-engine Owned by Engine team triaged-engine Triaged by Engine team
Projects
None yet
Development

No branches or pull requests