iwangjie commented on issue #14479:
URL: https://github.com/apache/dubbo/issues/14479#issuecomment-2257801150

   **Description:**
   
   There appears to be a potential issue in the `ServiceDiscoveryRegistry` 
class, specifically in the `DefaultMappingListener.onEvent()` method. The 
current implementation may lead to a race condition where a listener is 
prematurely destroyed, causing errors in subsequent service discovery 
operations.
   
   **Current Behavior:**
   When processing a `MappingChangedEvent`, if a new application name is found, 
the code attempts to remove the old listener (`oldListener`). If this listener 
has no other listeners attached (`!oldListener.hasListeners()`), it is 
destroyed, and the related subscription lock is removed. This can lead to a 
situation where a listener is destroyed even though it might be needed for 
future operations.
   
   **Problem:**
   If an application is only using one Service from the current consumer, the 
`oldListener` may be destroyed. Subsequently, when trying to use provider-by 
injection, the system fails to retrieve the Listener, resulting in an error: 
"Listener of cloud-caring has been destroyed by another thread."
   
   **Affected Code:**
   
   ```java
   if (oldListener != null) {
       String appKey = toStringKeys(toTreeSet(tempOldApps));
       Lock appSubscriptionLock = getAppSubscription(appKey);
       try {
           appSubscriptionLock.lock();
           oldListener.removeListener(url.getServiceKey(), listener);
           if (!oldListener.hasListeners()) {
               oldListener.destroy();
               removeAppSubscriptionLock(appKey);
           }
       } finally {
           appSubscriptionLock.unlock();
       }
   }
   ```
   
   **Potential Consequences:**
   
   1. Premature destruction of listeners
   2. Errors in subsequent service discovery operations
   3. Inconsistent state in the service registry
   
   **Suggested Improvements:**
   
   1. Implement a delayed destruction mechanism for listeners
   2. Introduce a reference counting system for listeners
   3. Create a listener pool instead of destroying listeners
   4. Perform a global state check before destroying a listener
   5. Redesign the system to be more event-driven, reducing dependency on 
specific listener instances
   
   **Additional Considerations:**
   
   - A thorough review of the entire service discovery and subscription process 
is needed to ensure proper listener lifecycle management in all scenarios.
   - Consider adding more logging and monitoring to facilitate easier diagnosis 
and tracking of such issues.
   - The overall design of the service discovery mechanism may need 
re-evaluation to better handle dynamically changing service topologies.
   
   **Steps to Reproduce:**
   
   1. Set up a Dubbo application with a service consumer using only one Service 
from a provider.
   2. Trigger a `MappingChangedEvent` that causes the listener to be destroyed.
   3. Attempt to use provider-by injection for the same service.
   
   **Expected Result:**
   The system should maintain the listener or recreate it as needed, allowing 
subsequent service discovery operations to succeed.
   
   **Actual Result:**
   The system fails with an error indicating that the listener has been 
destroyed.


-- 
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: notifications-unsubscr...@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@dubbo.apache.org
For additional commands, e-mail: notifications-h...@dubbo.apache.org

Reply via email to