Closed thiagosantoscunha closed 4 years ago
Thanks for the report. Given that no one else seems to be affected, my initial suspicion is that the problem's on the client side and the request is being sent to the wrong URL rather than the server sending the wrong response. When an error occurs, have you checked the URL that the faulty request was sent to was correct?
Unfortunately, I think it's going to be very hard for us to diagnose this without being able to reproduce the problem. Can you please use what you've shared above as the basis for a minimal sample that reproduces the problem in the form of a project that we can build and run? You can share it with us as a zip attached to this issue or in a separate repo on GitHub.
That autowiring of RestResponse looks kinda odd to me. I'm wondering, that's a custom class of yours?
Well spotted, @knoobie. Thank you. Unless that bean is request-scoped, it's going to cause thread-safety problems.
@knoobie e @wilkinsona.
I am extremely grateful for the answer. Come on!
RestResponse is a custom class for returning custom fields, in addition to which one or more entities can deliver. Here is a brief example of the class:
@Getter @Setter
@Component
public class RestResponse<T> {
private T data;
private List<ErrorResponse> errors;
public RestResponse(T data) {
this.data = data;
}
public List<ErrorResponse> getErrors() {
if (errors == null) {
errors = new ArrayList<>();
}
return errors;
}
}
@wilkinsona As seen in the javascript code sent, it is just a test that slightly simulates the palarerism of requests made asynchronously. For some reason, depending on the video, Spring returns data from another endpoint, as if it were in a cache. When I remove Spring's responsibility to inject my component, which is a very common pattern, it works normally. Despite being silly, it was very complex to understand this behavior, since Spring would take care of instantiating the class at the opportune moments of its call. Remembering, the error is not at the client's side. I say that with absolute certainty.
I have a friend, with extensive experience in the field, where he was helping me to identify, and he did something similar, which generated a similar error.
As suspected, your RestResponse
isn’t thread-safe. If the same instance is shared between your two controllers you will see the output from one controller in a response sent from the other controller. Rather than RestResponse
being a bean that is injected, each controller should create and return a new instance each time it handles a request.
Please let us know if the above fixes your problem. If it does not, we will need a minimal sample to be able to help further.
Yes, you are absolutely right @wilkinsona, but I thought Spring Dependency Injection would deal with this situation. When I remove the note and eliminate Spring's responsibility to take care, it works just fine.
I'm having the same problem
@thiagosantoscunha Spring cannot make your code thread-safe. It could have helped you here by making your RestResponse
bean request-scoped but there is no need to do so in this case. It will be more efficient to create an instance per request as I recommended above.
When I remove the note and eliminate Spring's responsibility to take care, it works just fine.
I'm not sure exactly what change you are describing here, but if you're creating a local RestResponse
instance in your @RequestMapping
method and returning it, this is exactly what you should do. RestResponse
isn't a dependency to be shared across your whole app. It's specific to each individual request and its lifecycle should match.
I am going to close this issue as it appears that everything is working as designed. If you have any follow-on questions about threading in Spring Framework, Spring MVC, and Spring Boot please ask on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
@wilkinsona It is not a customer problem, the test was run without problems in several browsers directly through the browser terminal, and I also tested it with other implementations in the Backend such as PHP Slim Framework and java Jersey and the problem did not occur
@insinfo Without some more context about your specific problem, I'm afraid we won't be able to help you. If you'd like some help, please ask a question on Stack Overflow or Gitter and the Spring Boot team and the rest of the Spring community will do their best to help you.
I set up a test scenario to deal with an error that was happening on my frontend.
Problem situation:
The problem was that I was making a request for a ‘/ api / v1 / phones’ route, Spring ends up returning ‘/ api / v1 / profiles’, as if the behavior were a cache. The data in the frontend, in some moments were not rendered, and that was when I decided to implement the stress test since I was not able to get it through the debug mode.
Besides one having thought of being a cache problem, like a route that returns a Phone API, it returns a Profile API, since the endpoint is configured with relevant entities?
Stress test scenario
The tests performed captured the following amount of errors:
Json
The time and number of requests made are stored in the image below:
Requests
The scenario is a mass of requests made in alternate times, for two endpoints, the profile and the phone, simulating parallel requests. See the Javascript code I implemented to perform the tests:
The problem was identified when the request was being made for the telephone API. The Java code that implements the Endpoint is very simple and is built in the following way:
My service method code is:
My custom query is:
My Profile controller is:
Libraries and versions:
Java 8 (Downgraded to Java 8, before it was 13, because I thought it might be a version problem) Spring 2.2.2.RELEASE Lombok JPA Postgre How to solve?
Would you like to know how to solve this problem? Why is a request being made to the phone api, returns an endpoint of the profile api?
Possible solution:
I don't know if this is a bug or some type of Spring Framework feature. But, when I remove Spring's responsibility to take care of the
response
andresponseList
instance, the error stops. I read Thread Safity too, can it be related?OBS:
I AM NOT USING CACHE!
Video link with stress test