Deep into Nacos server long polling processing core code

Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

ClientLongPolling

ClientLongPolling is a thread with the following code for its run method:

  • A scheduled task is started through scheduler.schedule with a delay of 29.5s
  • Add the ClientLongPolling instance to the allSubs queue, which maintains a long-polling subscription
  • After the scheduled task is executed, the ClientLongPolling instance is removed from the allSubs queue
  • MD5 is used to compare whether the groupKeys requested by the client have changed, and the result of the change is returned to the client through response
class ClientLngPolling implements Runnable{
    @Override
    public void run(a){
        // Start a scheduled task
        scheduler.schedule(new Runnable(){
            @Override
            public void run(a){
                try{
                    asyncTimeoutFuture=getRetainIps().put(ClientLongPolling.this.ip,System.currentTimeMillis());
                    allSubs.remove(ClientLongPolling.this);
                    if(isFixedPolling(){
                        // Compare the MD5 value of the data to determine whether it is modifiedList<String> changedGroups = MD5Util.compareMd5((HttpServletRequest)asyncCOntext.getRequest(),(HttpServletResponse)asyncContext.getResponse,clientMd5 Map);if(changedGroups.size()>0){
                            sendResponse(changedGroups);
                        }else{
                            sendResponse(null); }}else{
                        sendResponse(null); }}catch(Throwable t){
                    LogUtil.defaultLog.error("long polling error:"+t.getMessage(),t.getCause());
                }
            }
        },timeoutTime,TimeUnit.MILLSECONDS);
    	allSubs.add(this); }}Copy the code

According to the above code analysis, long polling means that the server does not return the request immediately after receiving it, but only returns the request result to the client 29.5s after the delay. The client and the server remain connected within 30 seconds without data modification. How do I notify you in real time when a configuration change is made via the console or OpenAPI? The scheduled task was executed 29.5s late, without achieving the results of real-time notification above. The class diagram shows that LongPollingService inherits AbstractEventListener

AbstractEventListener is an event abstract class with an onEvent abstract method. LongPollingService implements the following methods: AbstractEventListener = AbstractEventListener

@Override
public void onEvent(Event event){
    if(isFixedPolling()){
        
    }else{
        if(event instanceof LocalDataChangeEvent){
            LocalDataChangeEvent localDataChangeEvent=(LocalDataChangeEvent)event;
            scheduler.execute(newDataChangeTask(localDataChangeEvent.groupKey,localDataChangeEvent.isBeta,localDataChangeEvent.betaIps)); }}}Copy the code

In terms of event handling, the onEvent method of LongPollingService sees a LocalDataChangeEvent event, which publishes an event when the server’s configuration data is modified, and then focuses on the processing behavior after receiving the event.