-
Notifications
You must be signed in to change notification settings - Fork 656
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add an always
method on EventLoopFuture
#981
Conversation
Can one of the admins verify this patch? |
4 similar comments
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
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.
One minor nit, otherwise looks great.
Sources/NIO/EventLoopFuture.swift
Outdated
|
||
|
||
extension EventLoopFuture { | ||
|
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.
Minor nit: can we remove this whitespace?
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.
@Lukasa Done!
7778e37
to
0195ebc
Compare
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.
Looks good to me, I'll get @weissi to review as well.
Sources/NIO/EventLoopFuture.swift
Outdated
/// - parameters: | ||
/// - callback: the callback that is called when the `EventLoopFuture` is fulfilled. | ||
/// - returns: the current `EventLoopFuture` | ||
public func always(_ callback: @escaping () -> Void) -> EventLoopFuture<Value> { |
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.
@Lukasa do you think we should give users the result here? For whenComplete
we hand them the result so why not here?
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.
FWIW I just came across a case where having the above with the result (or alwaysSuccess
/alwaysError
) would have been helpful.
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 don't think I mind particularly. Arguably there are a family of functions here (giving them the name always
for now though the compiler wouldn't like it much) created by twiddling both the return value of the function and the return value of the closure it accepts:
Future<T>.always(_: () -> Void) -> Future<T>
Future<T>.always(_: () -> Void) -> Void
Future<T>.always(_: (Result<T, Error>) -> Void) -> Future<T>
Future<T>.always(_: (Result<T, Error>) -> Void) -> Void
Future<T>.always<U>(_: (Result<T, Error>) -> U) -> Future<U>
Future<T>.always<U>(_: (Result<T, Error>) -> Future<U>) -> Future<U>
Future<T>.always(_: (Result<T, Error>) -> Future<Void>) -> Future<T>
This proposal covers (1). (4) is currently spelled whenComplete
. (3) is what you're proposing instead, and can do everything (1) can do at the cost of being a bit noisier in the code when you want (1). (2) is what whenComplete
used to be in NIO 1, before we had a Result
type to use.
(5) is arguably a function that would be called mapBoth
, and (6) would be flatMapBoth
by analogy. (7) is akin to (4) but allows returning a Future
while persisting the result of the computation.
I think there could be a case made for providing all of these functions: the biggest challenge would be providing descriptive names, as we cannot rely on the compiler to provide overload resolution. (7) is the least obviously useful.
I think we should stick with always
being the name for this function. We should also provide (3) and call it something like alwaysWithResult
. Otherwise we'll force a lot of people to write always { _ in }
and that kinda sucks.
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.
@Lukasa Mostly agree, just that for whenComplete
we decided to only offer the 'with result' case (but we didn't name it whenCompleteWithResult
). Therefore, I'm not sure if for always
we should do always
and alwaysWithResult
... But I agree that the _ in
kinda sucks and obviously that the compiler won't like overloading at all. I'd probably still go for consistency with whenComplete
.
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.
No strong opinion here, I'm happy to follow your preference.
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.
@weissi @Lukasa If there's a version providing the result then I'd think alwaysWithSuccess
and alwaysWithError
would probably be requested too? Providing a value like this is pretty close to Java's peek
.
If that's the case then maybe these are distinct from the always
as it stands at the moment?
Future<T>.always(_: () -> Void) -> Future<T>
Future<T>.peek(_: (T) -> Void) -> Future<T>
Future<T>.peekError(_: (Error) -> Void) -> Future<T>
Future<T>.peekResult(_: (Result<T, Error>) -> Void) -> Future<T>
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.
Heh, I kind of like the peek
s. My only concern with leaving always
as is would be always
not giving you a value but whenComplete
giving you the result. Just looks a bit inconsistent, that's all :). Especially that in NIO 1 we had whenComplete
giving you nothing and we switched to whenComplete
giving you the result for NIO2 :).
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.
True, it's probably best to be consistent with whenComplete
even though I prefer the NIO 1 version of it! I think I ignore the result more often than not...
I would vote to change it back in some future version of NIO and introduce whenResult
to be closer in name to the other methods which provide a Result
to the callback. The above would then be analogues of the when{Complete,Success,Failure,Result}
which return the future.
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.
Sounds good. when{Complete,Success,Failure,Result}
make sense to me. Filed #986
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.
a87379a
to
aaadfba
Compare
@Lukasa fixed the failing build, sorry about that. I'm slowly engraving in my brain the reflex of running the sanity check locally. |
Motivation: apple#665 Modifications: * Add `always` in EventLoopFuture.swift * Add tests Result: NIO Users will be able to use `.always` to, well, always run an action wether the future succeed or not.
aaadfba
to
4d9771a
Compare
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.
Thank you! This looks mostly good but we should add the Result
for consistency
Motivation: Can be useful to developers and is consistent with the rest of the codebase Modifications: Add `Result<Value, Error>` to the callback Result: Result is available
@weissi your wish is my command 🙇 |
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.
Thank you! Looks good to me.
Motivation:
#665
Modifications:
always
in EventLoopFuture.swiftResult:
NIO Users will be able to use
.always
to, well, always run an actionwhether the future succeed or not.