Change ExecutionContext.errors from CopyOnWriteArrayList to Collections.synchronizedList(new ArrayList<>()) #2008
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We have been experiencing poor performance with our graphql-java application under heavy load during scale testing. During these tests, several other backends have also struggled which results in timeout or circuit breaker exceptions being thrown and mapped to GraphQL errors added to the response. We started profiling with Java Flight Recorder and reviewing the results in Mission Control. One finding is that there is significant blocking on the ExecutionContext.addErrors() method, which is backed by a CopyOnWriteArrayList. Researching CopyOnWriteArrayList vs. other options, CopyOnWriteArrayList blocks on write operations and is expensive because it has to create a new copy of the array on every write. It is ideal for situations with limited concurrent writes and many concurrent reads. For how the list is being used in this context, I would expect many concurrent writes and single threaded reads. This PR updates the ExecutionContext.error field to use Collections.synchronizedList(new ArrayList()), which is more performant way to support a synchronized list with concurrent writes. We ran a perf test with this change off of a local build and Mission Control was no longer reporting blocking in ExecutionContext.addErrors().
Sources: