How SDS Clients Receive Downgrade Event Notifications: Implementation Guide
SDS clients receive downgrade event notifications through a publish-subscribe mechanism that uses the DowngradeActionListener interface and the SdsDowngradeActionNotify class to dispatch events asynchronously via a dedicated thread pool.
The DiDi SDS (Service Degradation System) client library provides a robust notification system that allows applications to react to service degradation events in real-time. By implementing the DowngradeActionListener interface and registering with the central notification hub, clients can receive asynchronous alerts whenever a service point is downgraded. This guide explains the internal architecture and implementation details based on the source code in the didi/sds repository.
How Downgrade Notifications Work in SDS
The notification system follows a four-stage pipeline: interface definition, listener registration, event triggering, and asynchronous dispatch.
The DowngradeActionListener Interface
Clients must implement the DowngradeActionListener interface located in sds-client/src/main/java/com/didiglobal/sds/client/listener/DowngradeActionListener.java. This interface defines a single callback method that receives three parameters whenever a downgrade occurs:
point– The identifier of the degraded service pointdowngradeActionType– An enum (DowngradeActionType) describing the trigger reason (e.g.,THRESHOLD,DELAY,MANUAL)time– The timestamp when the downgrade was triggered
public interface DowngradeActionListener {
void downgradeAction(String point,
DowngradeActionType downgradeActionType,
Date time);
}
Registering Listeners with SdsDowngradeActionNotify
Listeners register through the static SdsDowngradeActionNotify class found in sds-client/src/main/java/com/didiglobal/sds/client/config/SdsDowngradeActionNotify.java. The registration method is thread-safe and stores listeners in a CopyOnWriteArrayList to prevent concurrency issues during iteration.
SdsDowngradeActionNotify.addDowngradeActionListener(myListener);
Event Triggering and Asynchronous Dispatch
When the client determines a request must be downgraded, the CommonSdsClient class invokes addDowngradeCount. This method, located at lines 69-76 in sds-client/src/main/java/com/didiglobal/sds/client/CommonSdsClient.java, updates the internal counter and triggers the notification system:
private void addDowngradeCount(String point,
long time,
DowngradeActionType downgradeActionType) {
SdsPowerfulCounterService.getInstance().downgradeAddAndGet(point, time);
SdsDowngradeActionNotify.notify(point, downgradeActionType, new Date(time));
}
The SdsDowngradeActionNotify.notify method enqueues tasks to a dedicated fixed-size thread pool (notifyPool). Each registered listener executes in a background thread, isolating the main request flow from listener latency or errors:
notifyPool.execute(() -> {
for (DowngradeActionListener listener : listeners) {
try {
listener.downgradeAction(point, downgradeActionType, time);
} catch (Exception e) {
logger.warn(...);
}
}
});
Implementation Examples
Lambda-Based Listener Registration
For simple implementations, use a lambda expression to register the listener directly:
import com.didiglobal.sds.client.config.SdsDowngradeActionNotify;
import com.didiglobal.sds.client.enums.DowngradeActionType;
SdsDowngradeActionNotify.addDowngradeActionListener(
(point, downgradeActionType, time) -> {
System.out.println(
String.format("Downgrade detected: point=%s, type=%s, at=%s",
point, downgradeActionType, time));
// Custom handling, e.g., push to monitoring system
});
A complete working example appears in the demo Spring Boot application at sds-example/sds-apache-dubbo-example/src/main/java/com/didiglobal/sds/example/DemoServiceApplication.java.
Class-Based Listener Implementation
For complex logic, implement the interface as a separate class:
import com.didiglobal.sds.client.listener.DowngradeActionListener;
import com.didiglobal.sds.client.enums.DowngradeActionType;
import java.util.Date;
public class MyDowngradeListener implements DowngradeActionListener {
@Override
public void downgradeAction(String point,
DowngradeActionType downgradeActionType,
Date time) {
// Example: send alert to external service
AlertService.send(point, downgradeActionType, time);
}
}
Register the instance using the same static method:
SdsDowngradeActionNotify.addDowngradeActionListener(new MyDowngradeListener());
Summary
- Implement
DowngradeActionListenerto define custom logic for handling downgrade events insds-client/src/main/java/com/didiglobal/sds/client/listener/DowngradeActionListener.java - Register listeners via
SdsDowngradeActionNotify.addDowngradeActionListener()for thread-safe addition to aCopyOnWriteArrayList - Events trigger in
CommonSdsClient.addDowngradeCount()when the system decides to downgrade a service point - Asynchronous dispatch occurs through a dedicated thread pool in
SdsDowngradeActionNotify.notify(), ensuring non-blocking execution with exception isolation
Frequently Asked Questions
How do I register multiple listeners for downgrade events?
Call SdsDowngradeActionNotify.addDowngradeActionListener() multiple times with different listener instances. The underlying storage uses a CopyOnWriteArrayList, so you can safely register listeners from multiple threads without synchronization concerns.
What happens if a listener throws an exception during notification?
The notification system wraps each listener invocation in a try-catch block within the notifyPool execution loop. If a listener throws an exception, the system logs a warning and continues processing the remaining listeners, ensuring that one faulty listener cannot break the notification chain for others.
Where exactly are downgrade events triggered in the source code?
Downgrade events originate in CommonSdsClient.java at lines 69-76 inside the addDowngradeCount method. This method is invoked internally when the client decides a request must be downgraded based on threshold, delay, or manual configuration settings.
Is the listener notification synchronous or asynchronous?
Notification is strictly asynchronous. The SdsDowngradeActionNotify.notify() method submits tasks to a fixed-size thread pool (notifyPool), allowing the main request processing thread to continue immediately while listeners execute in background threads.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →