Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example 2 with just CompletableFuture #9

Closed
woppa684 opened this issue Jan 24, 2017 · 4 comments
Closed

Example 2 with just CompletableFuture #9

woppa684 opened this issue Jan 24, 2017 · 4 comments
Labels

Comments

@woppa684
Copy link

woppa684 commented Jan 24, 2017

Something like this? You can argue whether it looks ugly but I still think it's not that bad.

    public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost) {
        CompletableFuture<Boolean> cf = new CompletableFuture<Boolean>();

        bank.decrement(cost).thenAccept(ok -> {
            if (!ok) {
                cf.complete(false);
            } else {
                inventory.giveItem(itemTypeId).whenComplete((s, ex) -> {
                    if (ex == null) {
                        cf.complete(true);
                    } else {
                        bank.refund(cost).thenAccept(ok2 -> {
                            cf.completeExceptionally(new AppException(ex));
                        });
                    }
                });
            }
        });

        return cf;
    }
@DanielSperry
Copy link
Contributor

DanielSperry commented Jan 24, 2017

@woppa684, Not bad. :D
but not quite equivalent.

What happens if inventory.giveItem throws an exception before returning a future?

For context woppa684 is responding to README.md :

So you like CompletableFutures? Try converting this method to use only CompletableFutures without ever blocking (so no joining):

import static com.ea.async.Async.await;
import static java.util.concurrent.CompletableFuture.completedFuture;

public class Store
{
    public CompletableFuture<Boolean> buyItem(String itemTypeId, int cost)
    {
        if(!await(bank.decrement(cost))) {
            return completedFuture(false);
        }
        try {
            await(inventory.giveItem(itemTypeId));
            return completedFuture(true);
        } catch (Exception ex) {
            await(bank.refund(cost));
            throw new AppException(ex);
        }
    }
}

@woppa684
Copy link
Author

Then that method is poorly programmed ;)

@DanielSperry
Copy link
Contributor

that happens... :)

You'd have to add an extra exception catcher and either repeat the refund block or wrap the exception as a future.

Then I think it would semantically similar to the async-await code.
Minus some potential mismatches on how the exceptions are nested.

@johnou
Copy link
Contributor

johnou commented Feb 21, 2017

Another nit is that if bank.decrement(cost) throws an exception thenAccept will never fire and the future returned by buyItem will never complete, might be a little more robust to use handle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants