My lead developer chatted with me about an issue we are running into with Flutter. We are building a mobile app and now we have hit a potential issue regarding threading. He said that Flutter by design is normally single thread. He thinks he can get more than one thread to work, but he can't wrap his head around how to get the threads to communicate with each other.
What we need is true background processing where something can be totally handed off to a separate thread to function then no matter where the app is at something can receive a notification from that thread to be able to correctly refresh the UI state.
A simplified example of this is:
User uploads an image
Image gets processed in a different thread
Badge shows up saying something like "image is processing"
Image processing thread gets completed
Badge goes away
The badge / UI thread would have to be send something from the image processing thread in this example. How could we tackle this with Flutter?
You can use isolates with send port and receive port to communicate between the Ui thread and the isolate.
Flutter Isolate Example
Here is a greater plugin to help you use plugins in an isolate flutter_isolate: ^2.0.0
Related
I'm working on a Twitter project, using their streaming API, built on Heroku with Node.js.
I have a collection of topics that my app needs to process, which are pulled from MongoDB. I need to track each of these topics via the API, however it needs to be done such that each topic is tracked only once. As each worker process expires after approximately 1 hour, when a worker receives SIGTERM it needs to untrack each topic assigned, and release it back to the pool again.
I've been using RabbitMQ to communicate between app and worker processes, however with this I'm a little stuck. Are there any good examples, or advice you can offer on the correct way to do this?
Couldn't the worker just send a message via the messagequeue to the application when it receives a SIGTERM? According to the heroku docs on shutdown the process is allowed a couple of seconds (10) before it will be forecefully killed.
So you can do something like this:
// listen for SIGTERM sent by heroku
process.on('SIGTERM', function () {
// - notify app that this worker is shutting down
messageQueue.sendSomeMessageAboutShuttingDown();
// - shutdown process (might need to wait for async completion
// of message delivery to not prevent it from being delivered)
process.exit()
});
Alternatively you could break up your work in much smaller chunks and have workers only 'take' work that will run for a couple of minutes or even seconds max. Your main application should be the bookkeeper and if a process doesn't complete its task within a specified time assume it has gone missing and make the task available for another process to handle. You can probably also implement this behavior using confirms in rabbitmq.
RabbitMQ won't do this for you.
It will allow you to distribute the work to another process and/or computer, but it won't provide the kind of mechanism you need to prevent more than one process / computer from working on a particular topic.
What you want is a semaphore - a way to control access to a particular "resource" from multiple processes... a way to ensure only one process is working on a particular resource at a given time. In your case the "resource" will be the topic... but it will still be the resource that you want to control access to.
FWIW, there has been discussion of using RabbitMQ to implement a distributed semaphore in the past:
https://www.rabbitmq.com/blog/2014/02/19/distributed-semaphores-with-rabbitmq/
https://aphyr.com/posts/315-call-me-maybe-rabbitmq
but the general consensus is that this is a bad idea. there are too many edge cases and scenarios in which RabbitMQ will fail to work as proper semaphore.
There are some node.js semaphore libraries available. I would recommend looking at them, and using one of them. Have a single process manage the semaphore and decide which other process can / cannot work on which topic.
In my BlackBerry app, the Locator.geocode(...) request is inside a Thread but it still blocks the UI in OS 5 devices. In OS 6 and 7 devices it works fine. The UI is not blocked.
From the moment Locator.geocode(...) is called till it finishes the UI is blocked and user can't interact with the application.
I guess this is a OS 5 issue. Is there a solution for this?
Update: First of all, thanks for quick replies.
I replaced Locator.geocode(...) call for Thread.sleep(...). The UI gets slowed down but not blocked. The simulator I'm using is 9300.
The Locator.geocode(...) request is inside a try..catch() block and it throws no Exceptions. After the call finishes it returns null (I'm using simulator) but no exception are being thrown.
For your information, this is what the console prints: (Using 9300 simulator)
**** Number of threads before creating Geocode class: 4
**** Number of threads inside Geocode class just before calling Locator.geocode: 5
**** Running on event thread: false
Locator.geocode(...) // UI blocks at this point(OS 5) till this
request finishes
Are you sure you have it running on a thread properly? It may be that OS 6+ is just responding faster, so you only notice the problem on OS 5. Try replacing the call to Locator.geocode() with a call to Thread.sleep(60000) to make sure the background thread is working properly.
From the Locator documentation:
*Requests for geocode information are synchronous, but can be interrupted by invoking cancel(). An application can use the Locator class to make only one request at a time. Making more than one request results in a MapServiceException. *
So thats one thing to check in your code. Make sure you don't make multiple request. Another possible problem:
If the LBS Map API is not installed on a BlackBerry device, requests for geocode information will throw a MapServiceException.
In both cases, an exception being thrown in a thread will terminate that thread, but this wont affect other threads like the event thread. So, without reading the code, I'd say your problem is not related to locator. It will be really helpful if you pasted some code or an exception trace.
I'm developing an application to track online Xbox Live, PSN, and Steam friends. The application performs a series of QNetworkRequests using a QNetworkAccessManager. The Xbox Live and PSN code use a QWebView to simulate a browser environment. The requests are performed correctly, but it slows down the main GUI thread until each request is finished.
Here's some example code:
void Steam::fetchFriends(QString username)
{
QNetworkRequest userXml("http://steamcommunity.com/id/" + username + "/friends/?xml=1");
m_nam->get(userXml);
}
I've created a signal to tell the GUI that friends have been downloaded and processed. Then the friends list is updated in the GUI. Some of my other code is more complex and it's possible that I need to move the processing code to another thread.
Can someone confirm that QNetworkAccessManager and QNetworkRequest are multithreaded or if they should be moved into separate threads?
QNetworkAccessManager is not threaded in its implementation. It is asynchronous and uses the event loop.
Those who claim they have needed to use it in a threaded state for performance reasons have noted that they need to create the instance specifically in the thread, and not try and move it to a thread. Here is a link to someone posting an example of such.
Before creating it in a separate thread, be sure first that you aren't doing any blocking operations that might cause the main thread to slow down.
when I test my app in cocoa I can read some "[Switching to process XXXX thread 0xXXXX]" that I'm not understanding...
When app creates a thread?
For example, when I mouseover some main menu items, I get [Switching to process XXXX thread 0xXXXX]
Why?
Apple can reject my application of app store for this reason?
Thx!
It's neither an error, nor a problem. It's a normal part of an application running in the debugger.
Do the menu items have a custom image, or use any animation effects?
The messages in the debugger are only showing that the application has switched to another thread to handle the processing and unless I am missing something, I don't think there is any need to worry about them.
Our app, which has been in the app store for a few months uses images and animation on certain sections and gets process switching notifications in the debugger and has never been rejected for that fact.
How do you handle update refresh rate from your worker function to your UI ?
Sending everything to the UI or maybe using a timer (from which side ? worker or UI ?)
In Windows apps, you generally want to use a Timer object in your GUI thread to poll for worker status -- it's easier, unless you have a really good reason to do something else...
You can't just make a function call to a UI routine from a worker thread in Windows. Undefined behavior will result, so watch out!
If your platform and development environment supports it some sort of asynchronis messaging system works well. Under Win32 I just use normal windows messages which I "post" (so they don't block the thread) and the standard main message thread of the UI picks up the messages and processes them. I usually define custom messages as well.
Using Timers is suboptimal, there should be no need to "poll" this sort of information.