Java Guava Framework on ListenableFuture - java

Is the below block of code valid? I saw this somewhere. But based on my own understanding, if we use immediateFuture to set the future to null upon construction.In theory, does the onSuccess code always execute, and it will never enter the onFailure block?
//public void doSomething(x,x){}
// doSomething(a,b)...
ListenableFuture<Void> future = Futures.immediateFuture(null);
Futures.addCallback(future, new FutureCallback<Void>(){
public void onSuccess(#Nullable Void aVoid){
//do something
}
public void onFailure(#Nonnull Throwable throwable){
//do something
}
return future;
}

First, your code as posted isn't valid. Just to start with, return future; belongs outside the callback definition. It is always easier to get help here if you copy-paste code samples that you know actually compile and demonstrate the behavior you're asking about.
Second, yes, in your scenario onSuccess() would always be called as soon as you add the callback.
I'm not clear what this is for, though. If you clarify what you're trying to do we can provide more useful help.

Related

Java Retrofit | Calling a method's return in a lambda expression

Suppose I have this piece of code
public String userName(){
//Retrofit setup here
MyAPI service = retrofit.create(MyAPI.class);
Call<Users> call = service.getUser();
call.enqueue(new Callback<>() {
#Override
public void onResponse(Call<Users> call, Response<Users> response) {
//suppose I get what I want here:
response.body().getUserName();
}
#Override
public void onFailure(Call<Users> call, Throwable throwable) {
//let's just say we return "User not found" onFailure
}
});
//return statement here
}
Is there a way I can have the String return statement of the userName() method in lambda expression? If not, what's the simplest way (with minimal amounts of processing) I can use to achieve this.
Retrofit has a isExecuted method for calls so I was thinking about using that in a while loop. But I just wanted to know if there's an easier way to do it before I proceed.
Thank you.
No, that is not possible. enqueue means: Do this asynchronously. As in, not now, later.
Where you wrote return statement here? That runs before the onResponse/onFailure methods do, so you can't 'move' the return statement there - your method must return (and therefore, know what to return) before the place where you want the return statement to be has even run, which makes that impossible.
This is the problem with asynchronous API: They suck to code against. This is what people are talking about when you say 'callback hell': You need to redesign all your code so that this method needs to return nothing; instead, all code that would act upon the return value needs to be packed up in a lambda and shipped to this method, so that you can invoke that lambda (and pass the thing you want to return, such as "User not found", as parameter instead).
There are probably ways to not use enqueue here, I'd look at that first.

Is there a good way to cancel/rollback an async realm transaction mid way through its logic?

I have been going over the realm documentation and found no feasible way of cancelling an asynchronous transaction from within the transaction "body" i.e. Realm.Transaction.execute()
So the only recourse I seem to have if I want to use the executeTransactionAsync() API's is to do something like:
realm.executeTransactionAsync(
new Realm.Transaction() {
#Override
public void execute(#NonNull Realm realm) {
// pretend we have some inter dependent database operations here
if (failureCondition) {
throw new Error("Failed transaction");
}
// and more here...
}
},
new Realm.Transaction.OnError() {
#Override
public void onError(#NonNull Throwable error) {
Log.e(LOG_TAG, error.getMessage());
}
}
);
Is there really no better way to do this? If re-ordering the operations such that a simple return would suffice and the transaction could be partially committed was an option that is obviously what I would do but what if it isn't.
Of course the above is technically functionally identical to just calling realm.cancelTransaction() in execute(), since it causes the attempt to commit the transaction that no-longer exists to throw an exception anyways. However, judging from the fact that the actual async transaction code behind this nice API doesn't check with realm.isInTransaction() before attempting to commit nor allows execute() to throw any checked exceptions neither approach seems to be something the designers even considered a valid use case.
I guess in the end I sort of answered myself, so perhaps the better question would be... is this a problem with the design of the API itself or am I just attempting to do something fundamentally wrong.

Taking the nusances out of AutoCloseable

Up front: I'm a C# guy doing Java right now. Some of these frustrations come from my lack of knowledge of Java.
First, is there a way to have a "safe" AutoCloseable implementation that does not require the Exception to be checked? If I'm implmementing my own class that won't throw from its close method, I don't see why I have to check it.
Second, is there a way to simplify the expression in the try statement where I don't care what's returned? For instance in C# I can do this:
using (new Disposable())
{
// yay!
}
and Java seems to force me to assign it to a temporary variable:
try (AutoCloseable iDontCare = getAutoCloseable()) {
// dont you dare use iDontCare
}
I wish I could simplify the Java to
try (getAutoCloseable()) {
// yay!
}
C# isn't quite Java; this is one of those gotchas you'll have to deal with going forward.
First, is there a way to have a "safe" AutoCloseable implementation that does not require the Exception to be checked? If I'm implmementing my own class that won't throw from its close method, I don't see why I have to check it.
You have to because it's mandated by the interface. Not just that, but it throws a checked exception, which does have to be handled at some level.
If you know for a fact that your code will never throw any kind of exception, you could still place the throwing of the exception in some kind of guaranteed-not-to-be-executed-block inside of your implemented close method. Or, implement your own interface which extends AutoCloseable and overrides close to not throw an exception.
Your first question:
Yes. You can implement AutoCloseable.close without the throws Exception part if your implementation doesn't throw checked exceptions.
Your second question:
No. The try with resources statement requires that variable. You can rename it to something like ignored or unused to make that clear.
final class Test implements AutoCloseable {
#Override
public void close() {
System.out.println("Closing");
}
public static void main(String[] args) {
try (Test ignored = new Test()) {
System.out.println("Not using ignored");
}
}
}
Makoto's answer does a nice job of addressing the first part of your question, so I'll attempt to address the second.
I think what you want is a try (without resources). For example:
try {
//yay!
} finally {
// always executed
}
The finally block will execute regardless of whether an exception is thrown or not.
Edit:
If you don't need anything to execute, you could just declare a new block
{
//yay!
}

GWT. Order of RPC call

There is something I can't understand. I have several RPC calls in my GWT code like:
private final PravformServiceAsync getPravformService = GWT.create(PravformService.class);
getService.getSome(new AsyncCallback<List<Pravform>>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(List<Pravform> result) {
pravformList = result;
}
});
which must executes at the program start. But with help of debugger I saw that code inside these calls doesn't execute at that time. It executes at the end of onModuleLoad() procedure executing, after all other code. It looks like my RPC calls executes on the second circle of code executing.
Please explain me why it happens.
That is what exactly asyncronous means,You never know when server returns that result to client,and mean while the flow continues.That is why people usually write their code in onSuccess(),so that futhure execution of flow stops until the request completes.
A clear cut execution and RPC Plumbing Diagram is there is Docs.
Please have a look.
The Async in the interface names stands for asynchronous. There's a reason you have to make those interfaces taking a callback rather than use the synchronous interfaces that just return a value. That reason is they're synchronous, aka non blocking.

How come Android's AsyncTask doesn't implement Future?

In Java, I've gotten used to working with Futures. Now I'm looking at Android, and AsyncTask implements almost all the same methods and covers similar lifecycles. But, if I want to be consistent and use Future all over my code, I have to wrap AsyncTask in a stupid wrapper, cause it doesn't actually implement Future.
All they'd need to add is an isDone() method, which seems like it would be trivial, then add implements Future<Result>. (added later: see my answer below for just how trivial it would be).
Any Android experts know some good reason / obscure bug it might cause why this hasn't been done?
From reading the actual code of AsyncTask.java it actually uses a Future task and then some more. A Future is a task that executes asynchronously on the go. An AsyncTask is scheduled on a queue for a single (or pool of) background thread(s).
An AsyncTask is actually more "superior" than a Future task. It does fancy scheduling and optimizations on top of Future's functionality. Just look at the API introduction levels. Future was introduced right from the start API 1.0. The AsyncTask object was introduced in API 3.
An AsyncTask has-a Future task, not is-a Future.
AsyncTask.java
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
#Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
I'm still interested in the theoretical reasons "why" not to use AsyncTask for a Future.
But, for the record, I ended up creating my own little class (shown below). Just extend it instead of AsyncTask if you want a Future. IMO, a cleaner way than the #Eng.Fouad idea of accessing the private mFuture within the code. (But thanks for the idea, it got me looking into the source code a bit!) YMMV.
public abstract class FutureAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> implements Future<Result>{
#Override
public boolean isDone() {
return AsyncTask.Status.FINISHED == getStatus();
}
}
AsyncTask is too simple. It's intended for short tasks which may take a few seconds, but for which you don't want to lock up the UI thread. If you actually need a Future, your task is probably too complex for an AsyncTask anyway.
You can check the status of an AsyncTask by calling getStatus(). This will return an enum which can be one of Status.PENDING, Status.RUNNING or Status.FINISHED.

Categories

Resources