-
Notifications
You must be signed in to change notification settings - Fork 123
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
Improve onItem/onFailure produceX method #165
Conversation
@jponge as discussed. |
29543ae
to
c12e928
Compare
I'm not really seeing how this solves the problem. I can't even see how the term "async" crept in there. Why would you not have called it In summary I don't see how these proposed changes solve the problem. I'm not even convinced that it's an improvement on the status quo. |
@gavinking yes, it's verbose, but the flatten approach is terrible. I ended up with 380 methods in Multi which is a no go. So, yes, there is still some work to do on the naming, and this PR is far from being finalized. I tried with Alternatives are welcome. |
Then let's discuss it. The rest of us don't even have a clear idea of the requirements and design constraints unless you write them down.
But as I understand it (I may not), the current PR uses |
Definitely. One of the main ideas of Mutiny is to avoid the flat design we are seeing in other libraries which leads to "let's use the IDE completion to pick the right operator without understanding it". That's what produced this idea of I'm ok with having shortcuts. We already have some (map, flatMap, concatMap). As illustrated in the other PR (#169), adding a
Let's try to summarize.
On a multi, it's a bit more tricky, because you have a stream of items. So, when you receive an item, you can:
|
Yes, I understand, and I support that goal. But, and this is a hug caveat: I don't think it's much better to have three interfaces with 100 operations each than it is to have one interface with 300 operations. It might even be worse. So what I've been trying to say is I want you to write down what you think are the fundamental, basic composable operations that your API needs to be built up from.
But I'm explicitly advocating fewer shortcuts. It seems to me that Mutiny as it exists today is sacrificing usability/understandability of the basic/fundamental operations, in order to provide a bunch of extra "convenience" or "advanced" methods that I don't feel like I'm ever going to need to use. But I might very well be wrong, because I don't have a clear idea of all the usecases! I think it's somewhat of a design smell to have various ways to access the same operation, e.g.
Great, but I want to see a summary like that which also includes all the basic operations needed for e.g. error handling, null handling, etc, as you see them. |
But even this characterization misses something I think. There's the distinction between:
And there's also a distinction between:
And these cases are orthogonal. It seems to me that the list above misses the need for In general, any operation you have which is going to accept a function, is also going to need a variation which accepts a So as a first step, that requirement needs to be made clear as a design constraint. |
It's not the case. We are far from 100 methods in each group. It gives you a navigation structure.
That was the first feedback I had: where are the map/flatMap operations. It's the basic operations from popular reactive libraries. I, personally, don't like
That has been provided (as |
And you need two variations of each of these operations, one accepting a plain function, and one accepting a |
Sorry missed that part:
Basically, whatever event you receive that's going to be one of these methods. Sometimes slightly differently, as for example, when you receive the completion event, you don't have an item. |
Right, I agree, I'm not in love with the name But no way in hell am I going to have hundreds of instances of |
The flattening part is only relevant when producing asynchronous items. A plain synchronous function would preserve the order. For example, let's have a multi: {a, b, c}.
|
Forgot one interesting case: the absence of an event ( ~ a timeout). |
@cescoffier These are the "basic operations" as I understand them:
Any of the above operations must accept either a plain (synchronous) function, or an asynchronous function packaged as a In addition, there are operations for working with But I know that this list isn't exhaustive because there's a whole bunch more functionality in Mutiny which isn't captured in the above list. And 2*8 = 16 operations isn't coming anywhere close to 350 methods. So I would dearly like to know where the additional >300 methods are coming from and what they are for. |
To recap, Mutiny was born mostly to solve the issue of RxJava having grown to use more than two types ( I was initially very unsure about the idea, but after having used it, I find the concept MUCH friendlier than the flat design, and much more intuitive. Now, it's necessarily more verbose, which is precisely why the most common opertions Now, as to this PR, I don't quite understand why If IMO we could drop the parallelism of While On the other hand, keeping the two names related could be good for discovery, but then I'd rather get As for the All in all, I don't find the new names much better if at all. I also think they miss the point that @gavinking was making by email, which is an entirely different strategy altogether, and which would perpahs be easier to discuss if @gavinking himself opened a PR with the API proposal so we can discuss it while trying it. |
OK, so the relationship between The semantics of |
I don't have a specific proposal because I don't understand the requirements well enough. I can only tell you what is making me uncomfortable in the current design... ... and that I don't think it's a binary choice between "one interface with 350 methods" and "what we have right now". (Again, I could be wrong.) |
@gavinking Here is a small excerpt from the Uni API. Many groups have been omitted (await, subscribe...), and some subgroups are omitted too (Name with ...). If you move all these methods a single class, you end up with (I can't remember the exact number) but roughly 350 methods. |
Me neither, but your proposal was a bit too abstract for me to follow. An implementation I could try ;) Even if the methods don't do anything, BTW. As long as interfaces are defined, I can try them on for size without running them. |
So, ok, you don't like
Alternative:
|
Alright, so that's helpful, thanks. And I think can already begin to discern some of those operations I which I would consider "non-fundamental". (And I can also see several operations which are duplicated in four places.) |
The way I see it, there's mostly the need to replace current imperative language constructs:
|
I should be able to share the editable version with you if you want.
Yes, which would mean the same name, but the listened event is different (so the parameter) |
Honestly that would work for me. But again, this is orthogonal with @gavinking 's proposal to groupd operations differently. This is mostly about names, and those proposed names seem fine to me. |
This PR was about names, not groups :-) |
Right. Precisely.
See here's where I really feel like I'm viewing these operations from a slightly different perspective. I feel like you guys are thinking of these operations from the point of view of manipulations on a stream. But my perspective is, for want of a better way of describing it, the perspective of the Haskell Now, of course, these perspectives are obviously equally-valid. But I think it does explain why I think that |
FTR these names look quite sane to me too. |
Looking more closely at this, I guess the thing that sticks out is how many different operations we have on Focusing on exception handling, I feel like I would be better served by a single "handle" method that comes in synch and async flavors. |
I actually used most of these methods in various app / framework. The only one that can be seen superfluous is |
* produceUni -> applyUni * produceMulti -> applyMulti * for the multi case, applyUniAndMerge, applyMultiAndConcatenate, applyUniAndMerge, applyUniAndConcatenate have been added * invokeUni have been added to fix #151
6ce73f9
to
9145400
Compare
I've renamed the method as listed in #165 (comment) |
(catching up after PTO) I'm the one who came up with the |
Why all methods have a parameter type as a suffix? Is the parameter type not enough? |
Because of Java. It won't see the difference between:
```
Uni<T> method(Function<X, T>);
Uni<T> method(Function<X, Uni<T>>);
Uni<T> method(Function<X, Multi<T>>);
```
Le jeu. 25 juin 2020 à 22:14, Željko Trogrlić <notifications@github.com> a
écrit :
… Why all methods have a parameter type as a suffix? Is the parameter type
not enough?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#165 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADCG7KWYY4BUXISNUU53RTRYOVZ5ANCNFSM4N5BXKOA>
.
|
Superseded by the proposal from #178. |
This PR provides better methods to chain async calls. This topic has been discussed in many issues, so here is my take on it.
The main idea is to use
applyAsync
for method returningUni
andgenerate
for method returningMulti
:Uni.onItem().produceUni()
->Uni.onItem().applyAsync()
Uni.onItem().produceMulti()
->Uni.onItem().stream()
Multi.onItem().produceUni()
->Multi.onItem().applyAsync()
/Multi.onItem().applyAsyncAndConcatenate()
/Multi.onItem().applyAsyncAndMerge()
Multi.onItem().produceMulti()
->Multi.onItem().stream()
/Multi.onItem().streamAndConcatenate()
/Multi.onItem().streamAndMerge()
Multi's
produceIterable
becamestreamFromIterable
.produceCompletionStage
becameapplyCompletionStage
.These names have been chosen conscientiously. I discarded many alternatives after having tried them and compare the pros and cons of each alternative. Typically
chain
(one popular option) did not fit onmulti
. Some alternatives were losing the event-driven mantra. Some shorter approach ended up mixing concepts or didn't express the intent correctly.The PR also adds
invokeAsync
to fix #151.Update:
generate
was not great, I changed it tostream
CC @kenfinnigan