-
Notifications
You must be signed in to change notification settings - Fork 14
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
Add future default methods #180
Conversation
Clarification (to my understanding of the PR here, please let me know if this is wrong)
Chat log in case anyone is interested for context(The chat log has been slightly modified to make it clearer) @lokka30Ivan - a thought came across my mind and I'd like to hear your opinion: Adding overloads on the subscriber methods for CompletableFuture conversions, instead of having to manually wrap it with These are just variants of the existing methods that return a // subscriber version
void retrievePlayerAccount(
@NotNull UUID accountId,
@NotNull EconomySubscriber<PlayerAccount> subscription
)
// CF version
@NotNull
default CompletableFuture<PlayerAccount> retrievePlayerAccount(
@NotNull UUID accountId
)
// both methods are present in the same file.
// nothing is removed. this is just a short hand that
// makes using CFs less tedious in Treasury. in theory this will be cleaner to use than wrapping the subscriber method with Subscriber#asFuture. People whinge about having to write concurrent code, so I am trying to find ways to make it easier for them to write. this is vital if we aim to have any adoption in the community. @MrIvanPlaysYes it will be cleaner I agree on this @lokka30 @lokka30Subscriptions are a useful feature, though Treasury should have always used CompletableFutures as the standard methods and provide defaulted subscription methods which just use CFs under the hood (opposite to what we have currently). Regarding the Subscription/CF thing: I still firmly vote that we should make a breaking change in Treasury v2 where CFs are the standard instead of Subscriptions. It will help us in the long term. This is the last and only breaking change I vote to make to Treasury, assuming we do not repeat the current mistakes in any new APIs. Another regret I have is releasing Treasury on SpigotMC with a release version (v1) rather than a beta version (v0) - a beta version would have otherwise allowed us to trial APIs for real world use without having to be very scared of the rare breaking change. I think we have ironed out almost everything with the economy API as is; it seems the only issues remaining are the subscriber/CF scenario, and the lack of documentation (which I will work on in my break). @MrIvanPlaysDocumentation is something which can be done at any state Unfortunately, I have a concern which if we do such breaking changes every major release of treasury then devs will view treasury as a 'can break always' API and push them away @lokka30I would dread using a library/plugin that breaks their API often - this is something I am currently dealing with for one of my own plugins (which try offer compat for another plugin which constantly breaks their API). I think we have only made one breaking change so far, which was to remove the API versioning system. I think this CF/Sub scenario is important enough that it deserves a breaking change soon. It will make it much easier for economy providers to be written since they can use subscriptions at their own option. This would be breaking change number 2 and almost certainly the last breaking change we will need to make to the economy API... I sincerely hope. For existing economy providers, they can either shift their usage of subscriptions to CFs, or they can do this:
|
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we using HashSets as collection of completable futures when CompletableFuture does not override hashCode ?
I have commented some places that I've seen that exceptions may be thrown that doesn't seem to be handled. I may have mist some
return FutureHelper.mjf(account -> account.isMember(playerId), | ||
Account::getIdentifier, | ||
futures | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FutureHelper#mjf
uses CompletableFuture#join()
which
throws an (unchecked) exception if completed exceptionally
but this excepcion is not handled in the mjf
method or this method, nor is it specifyed in the documentation that it's not handled
return FutureHelper.mjf( | ||
account -> account | ||
.hasPermission(playerId, permissions) | ||
.thenApply(triState -> triState == TriState.TRUE), | ||
Account::getIdentifier, | ||
accounts | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FutureHelper#mjf
uses CompletableFuture#join()
which
throws an (unchecked) exception if completed exceptionally
but this excepcion is not handled in the mjf
method or this method, nor is it specifyed in the documentation that it's not handled
BigDecimal balance = EconomySubscriber | ||
.<BigDecimal>asFuture(s -> account.retrieveBalance(currency, s)) | ||
.join(); | ||
BigDecimal balance = account.retrieveBalance(currency).join(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
join()
may throw an unchecked exception thats not handled
BigDecimal balance = EconomySubscriber | ||
.<BigDecimal>asFuture(s -> account.retrieveBalance(currency, s)) | ||
.join(); | ||
BigDecimal balance = account.retrieveBalance(currency).join(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
join()
may throw an unchecked exception thats not handled
CompletableFuture does nothing about the result but return it after it receives it. So it doesn't matter which collection type is used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a lot to add beyond MrNemo64's concerns. Nice catch of the unsafe operations in the PAPI hook.
I do still somewhat worry about inexperienced developers' implementations (it's easy to make mistakes, as we ourselves displayed in the PAPI hook!) as expressed in #161 (comment) and other referenced places, but this really is what I wanted from Treasury in the first place.
api/src/main/java/me/lokka30/treasury/api/common/misc/FutureHelper.java
Outdated
Show resolved
Hide resolved
I think I have another idea instead of futures and that is adding a way of combining subscriptions. Something like retrieveAccount(uuid, Subscription.combine(account -> account.retrieveBalance(...))); In half an hour I can come up with a better example (currently phone), but what I have in mind is probably the best as it is not breaking change and is much cleaner approach than asFuture and raw subscription. |
static <A, B> EconomySubscriber<A> thenCall(
BiConsumer<A, EconomySubscriber<B>> methodCall, EconomySubscriber<B> subscription
) {
return new EconomySubscriber<A>() {
@Override
public void succeed(@NotNull final A a) {
methodCall.accept(a, subscription);
}
@Override
public void fail(@NotNull final EconomyException exception) {
subscription.fail(exception);
}
};
} example usage: provider.retrievePlayerAccount(
uuid,
EconomySubscriber.thenCall(
(account, subscription) -> account.retrieveBalance(
provider.getPrimaryCurrency(),
subscription
),
new EconomySubscriber<BigDecimal>() {
@Override
public void succeed(@NotNull BigDecimal balance) {
// ...
}
@Override
public void fail(@NotNull EconomyException exception) {
// ...
}
}
)
); what do you think? |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dismiss my previous approval as I would like MrNemo and Jikoo's requested changes to be satisfied. Otherwise, I'm all ready to merge this in.
Ivan - if you would like me to work on anything in this branch, please let me know.
(I couldn't find where the 'dismiss review' feature was in GH, so I just posted this new review instead.)
what about doing the idea i gave instead of continuing this? |
Since we are the ones that write the papi hook, we are the ones in charge of handling the exception, arent we? If on the cache the future fails, no one is handling the exception right now
I have to give some thought to this |
Subscription chaining is a separate feature. I don't see why we can't add subscription chaining in, in addition to this CF defaults change. |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
api/src/main/java/me/lokka30/treasury/api/common/misc/FutureHelper.java
Outdated
Show resolved
Hide resolved
* Make FutureHelper#mapJoinFilter future-friendly * The method implementation now performs operations in an entirely non-blocking fashion. * Renamed to #mapJoinFilter per other suggestions. * Changed the filter parameter to be non-null: all usages were non-null anyway. * Change usage of FutureHelper.mapJoinFilter accordingly * Replace thenComposeAsync with thenCompose * Use pre-sized ArrayList rather than HashSet * Use consistent variable name
I've added a to-do list to the original post of this pull request so we can keep track of what changes need to be made regarding the concurrency changes in Treasury v2. Since work on this project seems to be in sparse bursts, I hope that it'll help us stay on track, rather than trying to reassemble what needs to be done each time. Please edit this to-do list. [link to top] |
Will be addressed in a different pr to branch 2.0.0 |
As discussed here on the Discord server.
To-do:
Basically, this will be the 2nd and last breaking change we will do in v2 - removing subscribers - what this is adding is default
CompletableFuture
implementations.