AsperforMias opened a new issue, #3480:
URL: https://github.com/apache/dubbo-go/issues/3480

   ## 👋 Thank you for your feedback!
   
   This issue tracks a potential stale provider problem in the Polaris 
interface-level registry path, similar to the Nacos initial subscribe snapshot 
issue fixed by #3479.
   
   ---
   ## 🔧 Environment Information
   
   ### 🚀 Go Version
   1.23+
   
   ### 📦 Dubbo-go Version
   main branch after #3479 / affected versions likely include releases with the 
current Polaris interface-level registry implementation.
   
   ### 🖥️ Server Configuration
   Dubbo-go or Dubbo provider using interface-level registry.
   
   ### 💻 Client Configuration
   Dubbo-go consumer using the Polaris registry implementation.
   
   ### 🌐 Protocol Configuration
   Any Dubbo-go protocol using interface-level registry discovery.
   
   ### 📋 Registry Configuration
   Polaris registry, interface-level registry path (`registry/polaris`), not 
application-level service discovery.
   
   ### 💾 Operating System
   🐧 Linux
   
   ---
   ## 🐛 Issue Details
   
   ### 📝 Bug Description
   
   `polarisRegistry.LoadSubscribeInstances` synchronously loads the initial 
provider instances and notifies the directory with per-instance `ADD` events. 
Later, `polarisRegistry.Subscribe` starts a Polaris watcher. The watcher sends 
the initial `WatchService` full instance list as `EventTypeAdd` events for each 
current instance.
   
   If an instance is returned by `LoadSubscribeInstances` but disappears before 
`WatchService` is established, the directory has already cached an invoker for 
the old instance. The watcher only emits `ADD` events for the current list and 
does not generate a `DEL` for the instance that disappeared between the 
synchronous load and the watcher startup. As a result, the stale invoker can 
remain in the directory cache.
   
   Relevant code:
   
   - `registry/polaris/registry.go`: `LoadSubscribeInstances` calls 
`GetInstances` and notifies each instance as `EventTypeAdd`.
   - `registry/polaris/core.go`: `startWatch` sends 
`resp.GetAllInstancesResp.Instances` as `EventTypeAdd`.
   - `registry/polaris/listener.go`: the listener forwards each instance as an 
incremental `Notify` event.
   - `registry/directory/directory.go`: incremental `ADD` is idempotent for 
existing keys but does not remove old keys; stale entries require an explicit 
`DEL` or a full-list `NotifyAll` refresh.
   
   ### 🔄 Steps to Reproduce
   
   1. Configure a Dubbo-go consumer to use the Polaris interface-level registry 
implementation.
   2. Start with provider instance A registered in Polaris.
   3. During consumer startup, let `LoadSubscribeInstances` load A and notify 
the directory with `ADD(A)`.
   4. Before the Polaris watcher finishes `WatchService` initialization, 
replace A with provider instance B, or remove A.
   5. The watcher initial response contains only the current instance list, for 
example B or empty.
   6. The watcher emits `ADD(B)` or no event for A, but no `DEL(A)` is emitted.
   7. The directory may keep the stale invoker for A.
   
   ### ✅ Expected Behavior
   
   Instances loaded by `LoadSubscribeInstances` should be reconciled with the 
first Polaris watcher snapshot. If an initially loaded instance is absent from 
the first watcher result, Dubbo-go should remove it from the directory cache, 
either by emitting a `DEL` event or by applying a full-list refresh semantics.
   
   ### ❌ Actual Behavior
   
   The initial synchronous load and the watcher path are not reconciled. The 
watcher initial snapshot is treated as incremental `ADD` events only. Providers 
that were added by `LoadSubscribeInstances` but are absent from the first 
watcher snapshot may remain as stale invokers.
   
   ### 💡 Possible Solution
   
   Apply a similar reconciliation strategy to the Nacos fix in #3479, or change 
Polaris watcher initial snapshot handling to full-list semantics:
   
   1. Keep the `LoadSubscribeInstances` result as an initial snapshot baseline 
and seed the Polaris listener/watcher before processing the first watcher 
response, so missing instances can produce `DEL` events.
   2. Alternatively, treat the first `WatchService` full instance list as a 
complete refresh and notify the directory via `NotifyAll`, allowing it to 
remove cached invokers not present in the current list.
   
   The implementation should be limited to the Polaris interface-level registry 
path and should not affect the application-level service discovery path, which 
already uses full-list `NotifyAll` refresh semantics.
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to