Sequential execution of async operations in Android - java

Sequential execution of asynchronous operations in Android is at least complicated.
Sequential execution that used to be a semi-colon between two operators like in do_this(); do_that() now requires chaining listeners, which is ugly and barely readable.
Oddly enough, the examples that demonstrate the need for chaining sequential operations usually look contrived, but today I found a perfectly reasonable one.
In Android there is in-app billing, an application can support multiple so-called in-app products (also known as SKU = stock keeping unit), letting the user, for example, buy (pay for) only the functionality that he/she needs (and, alas, also letting bearded men sell bitmaps to teenagers).
The function that retrieves in-app product info is
public void queryInventoryAsync(final boolean querySkuDetails,
final List<String> moreSkus,
final QueryInventoryFinishedListener listener)
and it has a restriction that the list must contain at most 20 items. (Yes it does.)
Even if only a few of these 20 are registered as in-app products.
I want to retrieve, say, information about one hundred in-app products. The first thought would be to invoke this function in a loop, but only one asynchronous operation with the market is allowed at any moment.
One may of course say "do not reuse, change the source", and even provide very good arguments for that, and this is probably what I will finally do, but I write this because I want see an elegant reuse solution.
Is there an elegant (=not cumbersome) pattern or trick that allows to chain several asynchronous operations in the general case?
(I underline that the asynchronous operation that uses a listener is pre-existing code.)
UPD this is what is called "callback hell" ( http://callbackhell.com/ ) in the JavaScript world.

You can sequence AsyncTasks one after the other by calling the execute() method of the next AsyncTask in the onPostExecute() method of the previous one.

Handlers are useful for sequential work on any thread, not only on the UI thread.
Check out HandlerThread, create a Handler based on its Looper, and post background work to the handler.

It looks like ReactiveX promises exactly this.
http://blog.danlew.net/2014/09/22/grokking-rxjava-part-2/
query("Hello, world!") // Returns a List of website URLs based on a text search
.flatMap(urls -> Observable.from(urls))
.flatMap(url -> getTitle(url)) // long operation
.filter(title -> title != null)
.subscribe(title -> System.out.println(title));
ReactiveX for Android:
https://github.com/ReactiveX/RxAndroid
Retrolambda: https://github.com/orfjackal/retrolambda (Lambdas for Java 5,6,7)

Related

How to Monitor/inspect data/attribute flow in Java code

I have a use case when I need to capture the data flow from one API to another. For example my code reads data from database using hibernate and during the data processing I convert one POJO to another and perform some more processing and then finally convert into final result hibernate object. In a nutshell something like POJO1 to POJO2 to POJO3.
In Java is there a way where I can deduce that an attribute from POJO3 was made/transformed from this attribute of POJO1. I want to look something where I can capture data flow from one model to another. This tool can be either compile time or runtime, I am ok with both.
I am looking for a tool which can run in parallel with code and provide data lineage details on each run basis.
Now instead of Pojos I will call them States! You are having a start position you iterate and transform your model through different states. At the end you have a final terminal state that you would like to persist to the database
stream(A).map(P1).map(P2).map(P3)....-> set of B
If you use a technic known as Event sourcing you can deduce it yes. How would this look like then? Instead of mapping directly A to state P1 and state P1 to state P2 you will queue all your operations that are necessary and enough to map A to P1 and P1 to P2 and so on... If you want to recover P1 or P2 at any time, it will be just a product of the queued operations. You can at any time rewind forward or rewind backwards as long as you have not yet chaged your DB state. P1,P2,P3 can act as snapshots.
This way you will be able to rebuild the exact mapping flow for this attribute. How fine grained you will queue your oprations, if it is going to be as fine as attribute level , or more course grained it is up to you.
Here is a good article that depicts event sourcing and how it works: https://kickstarter.engineering/event-sourcing-made-simple-4a2625113224
UPDATE:
I can think of one more technic to capture the attribute changes. You can instument your Pojo-s, it is pretty much the same technic used by Hibernate to enhance Pojos and same technic profiles use to for tracing. Then you can capture and react to each setter invocation on the Pojo1,Pojo2,Pojo3. Not sure if I would have gone that way though....
Here is some detiled readin about the byte code instrumentation if https://www.cs.helsinki.fi/u/pohjalai/k05/okk/seminar/Aarniala-instrumenting.pdf
I would imagine two reasons, either the code is not developed by you and therefore you want to understand the flow of data along with combinations to convert input to output OR your code is behaving in a way that you are not expecting.
I think you need to log the values of all the pojos, inputs and outputs to any place that you can inspect later for each run.
Example: A database table if you might need after hundred of runs, but if its one time may be to a log in appropriate form. Then you need to yourself manually use those data values layer by later to map to the next layer. I think with availability of code that would be easy. If you have a different need pls. explain.
Please accept and like if you appreciate my gesture to help with my ideas n experience.
There are "time travelling debuggers". For Java, a quick search did only spill this out:
Chronon Time Travelling Debugger, see this screencast how it might help you .
Since your transformations probably use setters and getters this tool might also be interesting: Flow
Writing your own java agent for tracking this is probably not what you want. You might be able to use AspectJ to add some stack trace logging to getters and setters. See here for a quick introduction.

How to dynamically update an RX Observable?

(Working in RxKotlin and RxJava, but using metacode for simplicity)
Many Reactive Extensions guides begin by creating an Observable from already available data. From The introduction to Reactive Programming you've been missing, it's created from a single string
var soureStream= Rx.Observable.just('https://api.github.com/users');
Similarly, from the frontpage of RxKotlin, from a populated list
val list = listOf(1,2,3,4,5)
list.toObservable()
Now consider a simple filter that yields an outStream,
var outStream = sourceStream.filter({x > 3})
In both guides the source events are declared apriori. Which means the timeline of events has some form
source: ----1,2,3,4,5-------
out: --------------4,5---
How can I modify sourceStream to become more of a pipeline? In other words, no input data is available during sourceStream creation? When a source event becomes available, it is immediately processed by out:
source: ---1--2--3-4---5-------
out: ------------4---5-------
I expected to find an Observable.add() for dynamic updates
var sourceStream = Observable.empty()
var outStream = sourceStream.filter({x>3})
//print each element as its added
sourceStream .subscribe({println(it)})
outStream.subscribe({println(it)})
for i in range(5):
sourceStream.add(i)
Is this possible?
I'm new, but how could I solve my problem without a subject? If I'm
testing an application, and I want it to "pop" an update every 5
seconds, how else can I do it other than this Publish subscribe
business? Can someone post an answer to this question that doesn't
involve a Subscriber?
If you want to pop an update every five seconds, then create an Observable with the interval operator, don't use a Subject. There are some dozen different operators for constructing Observables so you rarely need a subject.
That said, sometimes you do need one, and they come in very handy when testing code. I use them extensively in unit tests.
To Use Subject Or Not To Use Subject? is and excellent article on the subject of Subjects.

Is it possible to get a deep copy of objects using the VersionOne Java SDK?

Let's say I want to calculate the cumulative estimate of my defects. I do
double estimate = 0.0;
Double tEstimate = 0.0;
Collection<Defect> defects = project.getDefects(null);
for(Defect d : defects){
tEstimate = d.getEstimate();
if(tEstimate != null){
estimate += tEstimate;
}
}
Here each call to d.getEstimate() does a callback to the server, meaning this code runs extremely slowly. I would like to take the one-time performance hit up front and download all the info along with the Defect object, probably including getting some information I won't use, but avoid hitting the latency of a server callback during each iteration of the loop.
You are using the VersionOne Object model SDK. It does lack robustness because of the very thing you are complaining about. One of the inefficiencies is how it knows that you are requesting a list of assets but first gets all of the assets with a predetermined set of attributes such as AssetState and checks to see if it is dead asset. After this, it makes another call to get the same list of assets again but with your specified attributes. This could be remedied by applying a greedy algorithm that could grab a set a of attributes such that each member of this set is returned regardless of which attributes are requested in your .get_() method. Why? This already (sort of) happens in the Rest based VersionOne API as it stands. If the query returned all attributes, it would probably a little wasteful especially for humongous backlogs.
Anyway, the VersionOne will be deprecating the Object Model in the near future so if you plan on a lot of coding using the OM, consider this.
Here are some ways to circumvent this problem
1) Rewrite your code to use the VersionOne APIClient SDK. It has XML plumbing so that you will save you a lot of time writing your own. This is a little bit more verbose but it is more powerful, fast and efficient. The Object model is actually built upon the APIClient.
2) Rewrite your code using Java and the raw VersionOne Rest API - The requires that you understand http and the VersionOne Rest API.
3) If you cannot change from the Object model, you can mix the 2 sdks. When you need to read large amounts to data, just use APIClient code to manage that segment of the code. Kind of pointless when you can just learn the APIclient and use exclusively unless you have a huge investment in using the Object model and you can't change. The code gets mucky real fast. Not recommended.
The rest-1.v1 API endpoint exposes operations for assets, including DeepCopy. There is no client code that enumerates all of the operations, so you must first explore the asset using the meta.v1 API endpoint. Using the API Client backdoor from the Object Model, you can get to the classes that will allow you to call an operation once you know the name.

Client Server Assignment modeled using Java Threads (Producer/Consumer queues)

I have modeled a Client Server application using Java Threads and BlockingQueues (producer and consumer queues) as recommended in a previous question.
What I have is server has a BlockingQueue<Request> and it will push responses to clients' BlockingQueue<Response>. Problem now is how do I setup the client to call server functions at all. I have client's run()
while (true) {
Response res = responses.take();
switch (res.function) {
case "getReservationStatus":
TreeMap<Integer, Boolean> reservations = (TreeMap<Integer, Boolean>) res.data;
//System.out.println("getReservationStatus");
for (Entry<Integer, Boolean> reservation : reservations.entrySet()) {
//System.out.println(" - " + reservation.getKey() + " \t " + (reservation.getValue() ? "Booked" : "Available"));
}
break;
case "book":
SimpleEntry<Integer, Boolean> data = (SimpleEntry<Integer, Boolean>) res.data;
System.out.println(terminalId + ": Booking seat " + data.getKey() + " " + (data.getValue() ? "Successful" : "Unsucessful"));
break;
}
}
How do I somehow from my main() allow user to control what commands to send to the client? For now I hardcoded my "simulation" before the while
I am not sure if I understand your question, but I'll try to give an answer and a few ideas:
If you wish to implement a user interface for your programme, you must first define what your user can do with your programme. One popular way is to define use cases, and infer the interface from it. Let's say rather that we define functionalities from these use cases. So clearly you don't need that step anymore, since you have the kernel of your app done.
Your app is about pushing requests to a server to have them processed, and get responses. These requests, and their parameters, constitute a language understood by the server. In the same manner, the responses are a language the clients can understand, so you can model your UI around the requests language. If that language is simple enough, you can represent it as a tree, which is easy to implement in a UI.
You have basically three options:
text input UII: it's supposedly the simplest of all,
graphical UII (swing for instance),
web UI
In all three cases, the interface can be modeled as a list of menus and submenus to cover all the possibilities of requests: each request is an entry of your first menu, then each submenu level represent a refinement of the selected request. You can see here the resemblance with a tree I hinted at earlier. for a graphical UI, or a web one (after all it's a graphical UI too), this is trivial almost to achieve: you will find plenty of tutorials on the web for that. For text input, you can just display a numbered list of items (the menu), and ask the user to pick a choice.
Some notes:
Your app as it stands, models the interaction of several clients with one server. I am not sure how you can have that in your UI: perhaps you can enhance the language with a set of commands to spawn and manage clients, as well as indicate which client should send which requests.
If you feel adventurous and chose the text input, you could try modeling a real language to represent your queries, and implement a parser for that, this is a very broad topic too, but quite interesting. You might get into that later on in your studies anyway.
If the requests are complex or tedious to input, you could devise a template system, where the user could create a request template, name it, and then refer to it later on instead of inputing the same request again. See how we're getting closer to a small programming language here.
Web apps in the java world are usually based on fairly complex frameworks and toolings, you'll probably want to start with the other options first to get a good idea of UI.
As mentioned in my comments, for a graphical UI, try an IDE like eclipse or netbeans which let you easily define everything graphically and hook code to specific events (like pushing a button).

Java: Need efficient notifications between site users

I have a simple ajax game between 2 users with java backend (tomcat, spring). I need some good way of notifying one user that his opponent made a turn. Now all communication is done through database and waiting for opponent to finish his turn looks like this:
while(!timeout && !opponentIsDone) {
//...get the game record from db and check if opponent made turn
Thread.sleep(100);
}
Can I somehow get rid of this loop with sleep() and get instantly notified without a delay (but with timeout)? I can probably make some global static var and communicate through it, but I still will need similar loop only maybe timeout will be smaller.
I can't just call some method once the turn is done because it is all need to go to the browser through ajax and I can't push data there, only pull. So I need to have process that waits for the opponent.
I am looking for some light and simple solution.
Thanks.
You may want to look into Tomcat's advanced IO (Comet) support.
http://tomcat.apache.org/tomcat-6.0-doc/aio.html
I think you're looking for the Distributed Events (aka Subscriber/Publisher) pattern, and I believe Dojo Framework has implemented it:
http://ajaxpatterns.org/Distributed_Events
There are many ways to push notifications to a web client. Gmail's IM client is an excellent example of this sort of thing. This is often accomplished by holding an open HTTP connection in some manner, and this family of techniques is referred to as COMET. Wikipedia has an article on it, and there are blogs dedicated to the subject ( http://cometdaily.com/ ).
Even if you didn't use this technique, there are still many improvements you can make to the algorithm you identified in your question. One way would be to use a wait/notify sort of pattern or a subscriber/publisher approach. Another would be to return a "waiting for other player to make a turn" page immediately, and have that page automatically refresh every few seconds until the other player has taken his turn.
I think the solution you're looking for is COMET-style notification, though.
If you had a global static var of some sort, you could use a java.util.concurrent.BlockingQueue<T>
BlockingQueue<Turn> handoff = new ArrayBlockingQueue<Turn>(1);
// opponent thread
handoff.offer(myTurn);
// other thread can use
Turn otherTurn = handoff.poll( 90, TimeUnit.SECONDS );
if ( otherTurn == null )
// then no turn made
You can easily make the people wait for each other by using SynchronousQueue instead of ArrayBlockingQueue.
and of course it doesn't need to be global static -- it could be anything accessible to both users.
flex/flash has a real-time chatroom system (using remote-object programming).
you have to install BlazeDS (free) http://opensource.adobe.com/blazeds/, it comes with sample application. This is called AMF technology. I think Spring does support this AMF in one way or another.
http://www.adobe.com/devnet/livecycle/articles/blazeds_spring.html
http://blog.springsource.com/2008/12/17/using-spring-blazeds-integration-m1/
It's good for Flash based website. However, if you don't want to use flash, i think u can hide it or make it small enough, just to use it as a communication channel on your page.
Perhaps you have to find a way to notify your webpage/javascript after flash receive data from server.
Yeah, I know this method is a bit hacky, and it's not a clean way of doing thing :) just to provide an alternative for you.
DWR (Direct Web Remoting) is a package that allows you to make Java methods on the server directly available to Javascript (by creating a proxy). It has a feature called "Reverse Ajax" that is an easy way to handle push scenarios.
Perhaps consider Jetty Continuations if you aren't locked into Tomcat?
http://bill.burkecentral.com/2008/11/12/buggybroken-tomcat-6-comet-nio-apis/ has some discussion about Tomcat NIO

Categories

Resources