Duansg opened a new pull request, #7872:
URL: https://github.com/apache/shenyu/pull/7872
### What is the problem
1. **API docs pulled once per listener.** `DataChangedEventDispatcher`
called `LoadServiceDocEntry#loadDocOnUpstreamChanged` inside the listener loop.
With N listeners, one `DISCOVER_UPSTREAM` CREATE/UPDATE event ran the
doc-loading flow N times (dict lookup, tag read/write, swagger HTTP request).
The synchronous HTTP call also delayed the listeners after it.
2. **Doc lock left behind.** `PullSwaggerDocServiceImpl#pullApiDocument`
wrote the doc lock first and checked `canPull` afterwards. When the cluster had
already been refreshed, it returned without releasing the lock. Newly started
instances that should pull were then blocked until the lock expired (~60s).
### What this PR does
- `DataChangedEventDispatcher`: the loop only records that a listener
handled `DISCOVER_UPSTREAM`. Docs are loaded once after the loop, in a guarded
`finally` block:
- If a later listener throws after an earlier one applied the change, docs
are still loaded once, as before this PR. The listener failure is rethrown, and
a doc-loading failure is attached to it as suppressed.
- With no listener failure, a doc-loading failure propagates as before.
- No docs are loaded when no listener handled the event (no listeners, or
all skipped on a follower). This matches the existing behavior.
- `PullSwaggerDocServiceImpl`: the refresh-interval check (`isRefreshDue`,
same condition as before) now runs before the lock is acquired. An already
refreshed cluster takes no lock and writes no tag. The lock-holding paths are
unchanged.
### Impact
| Case | Before | After |
|---|---|---|
| Doc loads per upstream event | N (one per listener) | 1 |
| Already refreshed | 1 read + 1 lock write, lock left behind | 1 read, 0
writes |
| Refresh due, lock held by another pull | 1 read | unchanged |
| Refresh due, lock acquired | 1 read + 2 writes + HTTP | unchanged |
Out of scope: when the swagger endpoint returns 404 or the pull fails,
`refreshTime` is still not updated, so the next event pulls again. This is
existing behavior and is not made worse by this PR.
### Tests
- `DataChangedEventDispatcherTest`: one doc load for multiple listeners; no
load when no listener handled the event; still one load when a later listener
fails, with the original failure rethrown; doc failure kept as suppressed or
propagated.
- `SwaggerDocManagerImplTest`: 100 already-refreshed calls write nothing; an
expired lock is acquired and released when a refresh is due; a lock held by
another pull is never released.
Make sure that:
- [x] You have read the [contribution
guidelines](https://shenyu.apache.org/community/contributor-guide).
- [x] You submit test cases (unit or integration tests) that back your
changes.
- [x] Your local test passed `./mvnw clean install
-Dmaven.javadoc.skip=true`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]