Fix concurrent problems when initializing multiple GroupedOpenApi parallelly #1707
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.
Problem
Continuation of #1641
If a project has multiple
GroupedOpenApibean, they will be initialized parallelly. This lead to concurrent read and write ofAbstractOpenApiResource#HIDDEN_REST_CONTROLLERS.Since the list is not correctly synchronized, concurrent read and write might cause
ConcurrentModificationException(Collections#synchronizedListisn't thread-safe on iteration):Solution
There are 3 possible solutions:
Synchronize on the list before every read and write:
Use an fully thread-safe implementation for list, such as
CopyOnWriteArrayListGroupedOpenApionly triggers two write operations forHIDDEN_REST_CONTROLLERS, and the list is generally small, so the trade-off is acceptable.Reactor the initialization to eliminate concurrent write
Each
GroupedOpenApiwill try to add the same controllers toHIDDEN_REST_CONTROLLERSinOpenAPIService#initializeHiddenRestController, since the controllers are obtained from the sameApplicationContext.It's better to write to
HIDDEN_REST_CONTROLLERSonly once before parallel initialization. This can not only eliminate concurrent write but also avoid duplication.However, this refactoring requires more familiarity of Springdoc's code base, and it's beyond my powers at present.
This PR implements solution 2.
I also replaced
ADDITIONAL_REST_CONTROLLERS,HIDDEN_REST_CONTROLLERSwith set to avoid duplication. This will reduce the number of elements to iterate thus improving performance.