Android/Java sequence of serially executed tasks - java

How can I have a sequence of tasks that run one after another (Serially). I'm not using AsyncTasks, but the loopj AsyncHttpClient, but the question applies to other tasks as well.
The way it's structured is: Application has main method that performs multiple async calls. These calls are mutually serial, one must be run after another.
Main() calls FuncA() which fires an async request. Control is returned to Main()
The request handler calls OnFuncAComplete(), which triggers Main() to proceed:
Main() calls FuncB() which fires an async request. Control is returned to Main()
The request handler calls OnFuncBComplete(), which triggers Main() to proceed:
rinse, repeat
How can I write main to perform all these functions in lock-step, how can I pause Main() and in OnFuncXComplete "trigger" main back into action? My first thought was with ReentrantLock's, but I can't seem to get it to work.
Edit: I know I could just call FuncB() from OnFuncAComplete(), but then I'm getting down into callback hell and I want to avoid if possible.

It looks like there may be more than one solution for this. One possibility is to use SynchronousQueue for transferring tasks between your Main and a processor. AsyncTask probably will not be needed, instead your tasks can extend runnables and no need to make callbacks to "unlock" Main()
Create a processing thread that runs a loop and polls SynchronousQueue instance (possibly with timeout). Each element obtained from the queue is a Runnable that the processor thread just executes.
In your Main() you call FuncA(SynchronousQueue q, <...>), FuncB(SynchronousQueue q, <...>), etc. sequentially
Each of FuncX() inserts its runnable task into the queue (q)
Make sure that you can nicely finish your thread once there is no more tasks to run

Have a look at IntentService. It is a Worker service that has only one bg thread an requests are enqueued and processed in a FCFS manner. Responses from service to your Main can be delivered via a BroadcastReceiver that your Main should have registered beforehand.

Related

Advice for an asynchronous programming problem in Java

I have a set of classes which encapsulate a unit of work on Google Sheets. After the class's execute method is called, they pass a request to a service, bundled with a callback which the service should call on task completion. (As the tasks are non-critical and repeated frequently, the service just logs errors and does not call the class back if its request fails).
Stripped down, the tasks look like this:
public void execute() {
//preparatory stuff, then...
Request r = new Request(this::callback);
service.execute(r);
}
public void callback(Result result) {
...
}
The call to the service is synchronous but within the service, the Request is queued, executed asynchronously, and the callback is invoked on a new thread. Some of the tasks involve several service invocations, the callback methods may themselves create a Request with a second callback method and invoke the service again. I want that to be invisible to client code.
My problem now is that I would like to run the tasks asynchronously from client code and then execute an arbitrary handler after they are done. One way to do this would be to give the class a callback in the execute() method for it to call once execution is complete. But I'd really rather be able to do this inline in code, this sort of thing:
CompletableFuture.supplyAsync(() -> (new Task()).execute()).whenComplete((result, error) -> {});
The problem with that is, the completion of the execute() method does not signal the end of the task, as the task is still awaiting its callback. The other thing is, that callback might never arrive. I can't figure out how I should go about calling the task such that I can run it asynchronously and inline like in the code above and the whenComplete() will be invoked when the Task class explicitly decides it is finished. I'd also need a timeout, as the tasks's callback may not be invoked.
Any ideas? Note that I control the service invoked by the tasks, so I can change how that works if necessary, but I'd probably rather not.
I'd spend some time looking around in java.util.concurrent. Can't you just use an ExecutorService for a lot of this? You can submit() Callable code and get a future back, you can submit a list of Callables and give a timeout, you can call shutdown() and then awaitTermination() to wait for the processing to stop. You can get these notification callbacks by just submitting a Callable that constructs with the callback interface and invokes it when it feelsl like it's done.
Failing this, you might look at actors. Your concurrency pattern would likely be very easy in the actor model.
Going to answer my own question here: I just altered the task execute methods to return a CompletableFuture<TaskResult> with TaskResult containing the desired information. The task stores the CompletableFuture internally and calls complete() as needed in later callbacks. Not sure why I had trouble seeing this solution.

Java - series of async calls, but have to wait for a response of each async call before proceeding

The existing flow for single async call is as follows:
Make a call to an internal java service that sends the message based call.
At this point, that process is done.
An observer pattern has been implemented to be called when a response (message based) comes back to the java service.
The onResponse method is called and completion of the response should happen.
Edited to give more specifics:
I have tested with CountDownLatch and Phaser to get both of these scenarios working where my main thread is responsible for spawning off the parallel thread async call. The parallel thread completes, and the main thread waits to be notified that the response from the async call has been received. If the response signifies a success, move on to the next parallel call, and so on. Here is an example of Phaser that worked well. Question is, am I on the right path, or is there something easier/better?
main thread:
new Phaser(1);
for (iteration of number of request objects received){
create new thread, call serviceMethod.
phaser.arriveAndAwaitAdvance; //waits for arrival of registered party
if phaser.isTerminated
stop processing this request;
}
serviceMethod(){
phaser.register
perform call
}
onResponse(){
if SUCCESS
phaser.arriveAndDeregister(); //main thread should continue on to
next call
else
phaser.forceTermination
}
My comments on your question notwithstanding, I'll offer an answer, because I believe I can give you a different sort of answer without seeing any of your code:
By definition an asynchronous call is one where the caller does not block waiting for a response. So if you have a requirement to wait for a response, then you can avoid the problem you are describing by making a series of synchronous calls instead.
Again, paraphrasing a line from your question just a bit: "The process should be that I make the call, but wait for the response before triggering the next call." describes a synchronous calling scenario. In that sense, I suspect you are approaching the problem from the wrong direction.

BlockingQueue on main Service thread

My android app has a long running background service, which I also understand runs in the application's main thread and for that reason, any time consuming or blocking task should be moved to a separate thread.
Now, here is the situation, I don't understand/confused about:
When I bind to the service from an activity, i receive an reference to the service which allows me to invoke service methods from my activity. One of the methods allows me to pass a String object from the activity to the service, which is then added to a BlockingQueue. A separate worker thread which is started in the Service's onCreate method, checks the queue for available data and then performs the required task.
What I want to understand is, if at some point, the queue becomes full and an attempt to the queue blocks, will it affect the main thread the service is running on?
Yes. In this situation, if the queue becomes full, the calling thread will block (in your situation, the main thread). So this is a bad design.
The produced data coming from a field of an Activity doesn't force you to use it on the main thread. I suggest you use some Handler for your producer running on its own thread which will allow you to make the processing (and eventually waiting on the queue) outside of the main thread.
This is also good for communicating with your Service since you can use Handlers to communicate with a Service (see Android Services' guide).
Finally, if applying the produced data can be passed directly to an Handler using either
Handler.post(Runnable) or Handler.send(Message)

Telling the asynchronous job to wait in Java

I have a situation where sometimes (not always) my asynchronous job is not able to process results by the time needed and I have to return some kind of message to the client saying that his request is still being prepared by checking for it in the database.
The request and creating necessary object for it is handled in one database Transaction, the asynchronous process is handled in the different Transaction. I am using ScheduledThreadPoolExecutor by passing the runnable instance to the execute method.
The problems that sometimes the client makes a request and while the his browser is loading my asynchronous job is able to prepare the necessary data for it, but sometimes it isn't.
So my question is: Is there anyway I can tell asynchronous job to wait until the data is ready?
I am afraid that using just a Runnable instance you are not be able to tell the process to wait unless you sleep the Thread for sometime or looping and keep asking for the results which both are bad ideas.
In order to make this happen correctly, you should use a FutureTask for this by passing Callable instance to it's constructor. By overriding your call() method you should tell you transactional handler to do the job.
You also need to have some kind of a task manager which will add the task to the queue and creates a thread pool which takes and processes those tasks. For the queue purpose I would suggest to use for e.g.: LinkedBlockingDeque which accepts the generic type of FutureTask.
Also you should have a map of future tasks mapped by their name or something which takes the FutureTask as a value. In terms of waiting for the results when your Thread is processed the given FutureTask already you have to immediately remove it from the futures map. Then when your client requests you should check: if the futures map contains the task get the FutureTask from it and call futureTask.get() on it. This will wait until the task is finished.
This is just approach with which I would go. Hope this helps.

Java Thread to manage socket and run class method

I have a Java thread that I start so it keeps listening to a socket (considering the a socket read is blocking a thread is needed).
After the Thread receives the data from the socket it needs to call a method from a class.
Now I have two options to do this:
Declare an interface that is passed to the Thread and implemented in a class. When the thread calls the interface method the implementing classes will run it.
Or I can pass the class instance to the Thread as a parameter and then call the class method.
But I wanted to know if the thread blocks while the method is running.
I suppose so but I'm not sure.
I wanted the thread to have a Socket event behavior. What I mean is to only be responsible for reading the data from the socket and fire functions in the main Class, the one that called the Thread.
Yes, the thread will block while executing the method, so it can not read from the socket at the same time. No information will be lost, the transfer only takes longer and you can get a socket timeout if the computation takes too long.
If your method takes much time to run, you should execute it in another worker thread. I recommend to use an Executor for that.
You have various options :
Make your class a child class of Thread (easier code but you'll merge functionnal part - your main code - with a technical aspect (extending the Thread))
Make your class implements the Runnable interface and start a new thread with that Runnable (i often do like that). So your main code still remains in a overriden run method, but the inheritance tree is up to you (your main class can extend one of your other class)
Keep separated your main code / the thread with two classes (one for your main code, one for the thread), linking the two at your will (remember that if you make an inner thread inside another class, the inner thread can use any final properties, for example).
As stated in other answers, anything happening in your run() method is of course blocking the execution.
As a sidenote, if you're going to deal with threads and sockets, i strongly suggest you to have a look at NIO frameworks like Netty that are just there for this kind of behavior : event driven client/server application through NewIO sockets.
As another sidenote, i often use this pattern :
start an acquisition thread that will catch the event ;
push them in a linkedblockingqueue (queue.offer()) ;
have another thread that shares the same linkedblockingqueue (with queue.take()) : this operation is blocking, the threads will be blocked as long as the queue is empty ;
This is a very simple way to have one thread as "producer", and one thread as "consumer". You can even have various consumers awaiting on the same queue.
But I wanted to know if the thread blocks while the method is running
Yes it does block.
If inside run you call a method to process something it doesn't matter if that is an interface etc as you ask it only matters what does the method actually do
In your case you have only 1 option.
Make sure that you return the control back to your socket listening thread asap.
This can happen by designing/mandating the processing class to handle the processing in a different thread.
Actually your problem is not something new. In event based designs there is the requirement to process the event as fast as possible so as to not block the event queue based flow.
And this is how I would recommend you to design arround. Not use any interface to interact with the listening thread but register an event listener(s).
When an event occurs i.e. your listening thread reads data, it will pass the data as event to your listener(s) at which point of course it will block.
Then you should start a new thread to do the processing and the listening thread can continue with its work

Categories

Resources