Python multithreaded server and asynchronuous websocket communication with Android clients - android

I have an Android client app that sends some data to a server in Python, where the Python server is supposed to run a long time-consuming operation/computation and return the results to the client.
To do so, I initially started using Flask with Python on the server side, and an asynchronous android http library on the client side to send the data via http POST. However, I quickly noticed that this is not the way to go, because the computation on the server takes time which causes problems such as the client getting timeout errors ... etc.
Then, I started using Tornado's Websockets on the server side, and an android library for websockets on the client side. However, the first main problem is that when the server is running the time-consuming operation for a given client, the other potential clients need to wait ... and it seems a bit of a pain to make tornado work in a multi-threaded setting (as it is originally planned to be single-threaded). Another minor problem, is if the client goes off-line while the server is processing his request, then the client might never get the result when he connects back.
Therefore, I would like to ask if you have any solutions or recommendation on what to use if I want to have such a setting with an asynchronous multi-threaded Python server who is supposed to do heavy-cpu computations with data from a client without making the other potential clients wait for their turn; and potentially making the client able to get the result from the server when he connects back.

FIrst of all, if you're going to do cpu-heavy operations in your backend, you [most probably] need to run it in separate process. Not in thread/coro/etc. The reason is that python is limited to single thread at time (you may read more about GIL). Doing cpu-heavy operation in multithreading gives your backend some availability, but hits performance overall.
Simple/old solution for this — run your backend in multiple process (and threads, preferably). I.e. deploy your flask with gunicorn, give it multiple worker processes. This way, you'll have system that capable of doing number_of_processes - 1 heavy computations and still be available for handling requests. Limit for processes is usually up to cpu_cores * 2, depending on cpu arch.
Slightly more complicated:
accept data
run heavy function in different process
gather result, return
Great interface for this would be ProcessPoolExecutor. The drawback is — it's harder to handle failures/process hanging over
Another way around is task queue + workers. One of most used is celery. Idea is to
open WS connection
put task in queue
worker (in different process or even different physical node) eventually picks up task, compute it, put result in some DB
main process gets callback/result of long polling over result DB
main process sends result over WS
This is more suited for really heavy and not real-time tasks, but gives you out-of-the-box handling for failures/restarts/etc.

Related

Continuous data transmission between UI Thread and Worker thread running TCP Client

I have an app (Android Studio) that continuously generates data (Joystick coordinates) based on the user touch, that I want to stream continuously to my NodeMCU using Socket programming. I implemented an Async Task to do this on a separate tread.
I pass the bytes of data to the AsyncTask via execute() method from the Main Activity. The doInBackground method opens the socket connection and transfers the data byte to the server and then closes the socket. With the next available user input this process gets repeated again. Now for obvious reasons, this is not very effective.
I haven't figured out a way to keep streaming the bytes from the Main Activity to a buffer on a separate thread which would in turn keep streaming the bytes to the NodeMCU without repeatedly closing the socket.
So here is the question. What would be the best solution for my problem? I have been reading about so many different things like Services, Threads, Loopers, RxJava and it seems I am getting no where.
Well my Preferences would be:
RxJava - because RxJava is supercool, solves a lot of problems like switching schedulers between UI and IO and is close to your domain. Think of your joystick device as an Observable constantly emitting events (thats exactly whats RyJava is good for).
Services - can be done efficient. It will come down to an Observer-Pattern provided by the Service. In Android its is common to expose some hardware through services.
Loopers - because they are a little more lightweight and easier to manage than Threads.
Threads - possible, but probably most work to do on your side and most likely to produce subtle bugs.

How to use RxJava for asynchronously executing a dynamic list of consecutive dependent operations?

I'm working on an Android Service Library (AAR) that has to execute a variable number of processes consecutive/pipelined on an input (JSON) in the background.
Thereby, the next process takes the output of the previous process as input.
The processes can involve literally every kind of possibly long running tasks (http requests, IO/DB requests, heavy data crunching, ...)
It shall be possible to log the progress between every process and get the final output of the last process e.g. in a subscriber (library service thread).
The processes should run stable, in case internet connection is lost or parent application state is changing.
I'm currently using Robospice in my library to achieve stability for multiple requests...
This question: How to implement a sequence of consecutive operations using rxjava
is related to my question, except I ask for a variable sequence of operations.
Is it possible achieve this with Rxjava? If yes, how? If not, what are other options?
My idea how to do it somehow without Rxjava:
Keep Process count for every request
Processes[counter].execute(result, callback)
Callback-OnSuccess(result): increase process counter and start Processes[counter] with result
But I'm not experienced with thread handling and think this is not very robust and maybe it doesn't even work or blocks the calling thread (what makes the library not usable for this time)

Should I send parallel requests from the client, or send one request and execute them on the server in parallel?

I am using retrofit on the android side and node.js on the backend side.
Retrofit allows async requests, so can I send two requests from android in parallel on the server and get the result back, or I can send one request and use caolan async to run two different requests in parallel.
Which request should I use from retrofit? Should I send parallel requests or execute them as one request in parallel?
I think the second approach is better because the first approach increases server requests which adds to the server load.
Please tell me, which approach should I use?
Your milage may vary but in general batching saves opening and closing multiple connections. I've had gains in performance once I started batching multiple requests together rather than having to open and close a connection for each request. Best way to find out for your use case is to write a test for both and compare.

REST client throughput in Android

I have a project going where several devices submit data to a central server on the local network using a REST service. I am trying to determine how complex of a client I need in Android. Each device will be generating data quickly (i.e. sensor data), so its client will send frequent requests but can also bundle data into larger, less frequent ones. I'd estimate the throughput per client at about 50KB per second.
Is a REST client an appropriate strategy? How much data would be too much? Any thoughts on this would be appreciated.
Even if it is advisable, there are several options to choose from such as
Roll your own using HttpUrlConnection or HttpClient
Volley (example) from Google, which uses four threads
Ion from koush
Others such as https://github.com/darko1002001/android-rest-client
I do have my own implementation from a couple years ago that uses HttpClient, but it's probably outdated.
It greatly depends on your exact needs, but
you also could just send a list of sensorDatas every 10minutes for instance (numbers figured), as you mentioned before. Sending those collections has the charm that the client could determine when the collection has to be sent, like every 10min or every 10 entries, or before the device goes into stanby/onPause etc.
On serverside there must be a way of putting/posting collections created by the client. Depending on your needs the collection then could be seperated into single resources on the server.
The clientside implementation should not be far from posting single sensorData. It's just bundeling and sending.
Socket communication on the other hand renders your RESTful Service pretty useless.
Because I got the impression, that the process isn't that complex, I would go for an own implementation using HttpClient AND I would read about the different HttpClients beforehand. (There is an apache one, and a fork of it rolling with the Android SDK. I am currently unaware of if this gets you in trouble later).
Because you are constantly sending data, I would prefere to create a Socket communication. With REST you would need to send a new POST for every chunk of data including the http overhead. The Socket communication will be keept alive and the overhead should be less.

How to manage Android- to external device communication via web API?

I'm building a program which interfaces with a device which runs its own internal web server. I communicate with the device via a web API.
Basically what happens is that a GUI is presented to the user, where the user can make certain modifications to the device. These changes are communicated to the device, and results are returned through XML. The device needs to converse with the program in the background more or less continually (say every 15s or so) to update certain values to the user.
My structure that I'm envisioning is something like this:
UI - Main - Networking - XML Parser.
I'm looking for advice on how to manage these. I understand the UI thread should be separate to provide a smooth experience to users. I also understand that the networking should be at least an asynchronous task. I'm not so sure about how to handle their interaction, and make sure things are happening smoothly and effectively.
My idea is that Main will handle passing data around, telling the networker to send specific messages or changes, passing the returned XML to the parser, and then passing the parsed values to UI for handling.
I'm curious though for advice beyond that.
Have a look at creating a service that is created with your Activity. Without knowing the details of your plan, a Service looks like the optimal solution to perform all the heavy work.
UPDATE:
You could have the calls to web API run in a Service and, when needed, update the UI through an interface. You would have to instruct the Service to run on its own thread, so thread safety is an issue, but less trouble in the long run than using an AsyncTask.
Have a thought about using Google C2DM.
In your case,
Pros -> Less battery use, coordinated network traffic, Don't have to run a continues service and doesn't have the potential of being killed when the device runs out of resources.
Cons -> You have to post the results manually back to your internal server, and server should know which request the device is replying to. Communication is disconnected and may not be real-time. Requires a google account on the device and Google market.

Categories

Resources