-
Notifications
You must be signed in to change notification settings - Fork 30
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
Clarify usage of LRAClient#getCurrent() #86
Comments
The intent of getCurrent was that the returned LRA is the one that gets propagated on JAX-RS business requests and the last LRA that the client created (whether is was via an annotation or explicitly via the client API) that is still running is the one to be propagated. Doing anything else will only serve to create confusion in the mind of the developer. Also if you force the business author to explicitly set the context on the JAX-RS header on business invocations then I would argue that we are no longer CDI first. |
@mmusgrov ok, but we need to rewrite javadoc for the method as it seems that getCurrent() should be replacing LRAClient#LRA_HTTP_HEADER. WDYT? |
Agreed, I will update the javadoc. Also I would like to point out that I used to have a corresponding method called setCurrent to enable business methods to change the notion of the current active LRA. Do you think it is still okay not to have that method in the API? |
Can you come up with some use-case please? |
The business method invokes two different services (asynchronously) and wants the two invocations to run with a different context so he needs to creates 2 LRA's and then ensure that each invocation uses the correct context. |
In that case thread context won't get propagated in the async threads so it would be better to start LRAs in the individual async invocations directly. Maybe I don't understand what you mean. |
Just from other perspective. Isn't a bit confusing the current behaviour in situation like this? The LRA is started with
|
@LRA
void bisinessMethod() {
callAServiceInCurrentLRA();
callAnotherServiceInNewLRA();
callAnotherServiceInNewLRA();
}
void callAnotherServiceInNewLRA() {
URL lra = lraClient.startLRA(null, "xxx", LRA_TIMEOUT_MILLIS, ChronoUnit.MILLIS);
lraClient.setCurrent(lra);
invokeService();
lraClient.closeLRA(lra);
} |
I have another doubt, just how this should work. If
|
Yes it is correct. The model is that each time a new LRA is started it is pushed onto a stack and each time an LRA is finished it is removed from the stack (not necessarily popped unless it was the last one to be pushed). The getCurrent() method will always return the last LRA that was pushed onto the stack. I think this model is the one that makes intuitive sense. Notice that with this model there is nothing special about LRAs started and ended via annotations. Also, given this model I thought it useful to also provide a setCurrent method but I was asked to remove it in one of our hangouts. @ochaloup Does this explanation provide a satisfactory answer to both of your questions? Finally, providing an operation to look at the stack is a possibility but I think that would be overkill. |
For the first one, I understand it it's just up to developer to find out the state. For the second one, yes. I think this model should not provide the |
This point is not connected with the previous discussion. If not said elsewhere else the specification should define that finished method annotated with the
|
@ochaloup Agreed the javadoc needs to make this clear. I will go ahead and raise a PR against this issue (using text similar to my last response) and then we can further discuss it there if required. On the issue of Furthermore, it is a specification goal to enable the developer to be able to structure his application using the features that LRA's provides:
and being able to control which context gets propagated on different business requests facilitates the above goal and without the feature the business code that is structured in this way is likely to be more complex. |
@xstefank @ochaloup I updated my last comment with a reference to the spec to justify why |
Personally I would still prefer explicit LRA id propagation so the user can choose which id will get propagated but that is different discussion. For URL id1 = lraClient.startLRA(null, "id1", 0L, ChronoUnit.SECONDS);
URL id2 = lraClient.startLRA(null, "id2", 0L, ChronoUnit.SECONDS);
URL id3 = lraClient.startLRA(null, "id3", 0L, ChronoUnit.SECONDS);
...
lraClient.setCurrent(id1);
makeBusinessRESTCall();
...
lraClient.setCurrent(id3);
makeAnotherBusinessCall();
...
lraClient.setCurrent(id2);
makeAnotherBusinessCall2();
... instead of: URL id1 = lraClient.startLRA(null, "id1", 0L, ChronoUnit.SECONDS);
URL id2 = lraClient.startLRA(null, "id2", 0L, ChronoUnit.SECONDS);
URL id3 = lraClient.startLRA(null, "id3", 0L, ChronoUnit.SECONDS);
...
makeBusinessRESTCall(id1);
...
makeAnotherBusinessCall(id3);
...
makeAnotherBusinessCall2(id2);
... where all business calls are just wrappers around basic JAX-RS Client API or preferably MP REST client seems to me a little redundant. User is still propagating the header but implicitly. So instead of doing .header(LRAClient.LRA_HTTP_HEADER, lraId); somewhere between the lines the user needs to do lraClient.setCurrent(lraId); AND then very similar call like the first one just omitting the header. @mmusgrov I am sorry if I'm missing what you have in mind. However I still don't have a strong preference here. If we include it, it will be harder to remove it while on the other hand if we don't include it we can add it in 1.1 assuming community requests this functionality (we can throw it as an idea to the MP google group) |
my two cents: my personal preference is that for the |
Don't forget that this is a CDI first project. |
If it is CDI first then couldn't both setCurrent and getCurrent be removed because you can't do that with annotations? |
An annotation based participant can get and set the active LRA via @HeaderParam(LRA_HTTP_HEADER) String lraId |
Indeed, getCurrent and setCurrent can be removed. |
Ha ha, you are right, I have just argued that getCurrent and setCurrent are superfluous. In that case I agree that the methods can be removed. |
I beg for apologies I forget the same is currently possible to get from header. |
So @xstefank can we close this or do you want it left open to be discussed in the 1.x round of issues? |
@mmusgrov If we are to bring the LRAClient interface in the same form as it is right now to 1.x (once it is removed for 1.0) please do keep this issue open as there will be this question rising again once users will be able to use LRAClient in CDI beans where |
In scenario when getCurrent is called repeatedly in the same method which starts new LRAs it's not clear whether we want behaviour where each newly started LRA represents the current context:
or the method should always return the context which was started when the method was entered:
The javadoc states:
The text was updated successfully, but these errors were encountered: