Zookeeper 3: implementation of Listener Watcher

Source: Internet
Author: User
Tags data structures serialization zookeeper
watcher implementing data structures and streaming diagrams

Note: The picture is too large, right-click new tab to open the picture, enlarge view

Client client receives notification message for watch event

All watcher final callbacks receive messages in the CLIENTCNXN internal class Sendthread. The XID field of the message body of the notification event notification that the server sends to the client is special, which is-1.

Class Sendthread extends Thread {private long lastpingsentns;
        Private final Clientcnxnsocket Clientcnxnsocket;        
        Private random R = new Random (System.nanotime ());

        Private Boolean isfirstconnect = true; void Readresponse (Bytebuffer incomingbuffer) throws IOException {Bytebufferinputstream bbis = new Bytebufferi
            Nputstream (Incomingbuffer);
            Binaryinputarchive Bbia = binaryinputarchive.getarchive (bbis);

            Replyheader REPLYHDR = new Replyheader ();
            Replyhdr.deserialize (Bbia, "header");
                    if (replyhdr.getxid () = =-2) {//-2 is the XID for pings if (log.isdebugenabled ()) {
                            Log.debug ("Got ping response for sessionid:0x" + long.tohexstring (SessionID)
                        + "after" + ((System.nanotime ()-lastpingsentns)/1000000)    + "MS");
            } return;               
                } if (Replyhdr.getxid () = =-4) {//-4 is the XID for Authpacket                    
                    if (replyhdr.geterr () = = KeeperException.Code.AUTHFAILED.intValue ()) {state = states.auth_failed; 
                            Eventthread.queueevent (New Watchedevent (Watcher.Event.EventType.None,                                      
                Watcher.Event.KeeperState.AuthFailed, null));
                            } if (log.isdebugenabled ()) {log.debug ("Got auth sessionid:0x"
                + long.tohexstring (sessionId));
            } return; } if (Replyhdr.getxid () = =-1) {//Currently we are only interested in XID =-1 for WATCHEDEVENT events Notification//-1 mean s notification if (log.isdebugenabled ()) {Log.debug ("Got notification sessionid:0x "+ long.tohexstring (sessionId)); } watcherevent event = new Watcherevent ();

                Watcherevent is used for serialization and deserialization, the internal field order and Watchedevent are fully consistent event.deserialize (Bbia, "response"); Convert from a server path to a client path if (Chrootpath! = null) {String server
                    Path = Event.getpath ();
                    if (Serverpath.compareto (Chrootpath) ==0) Event.setpath ("/"); else if (serverpath.length () > Chrootpath.length ()) Event.setpath (Serverpath.substring (chrootpa
                    Th.length ())); else {Log.warn ("Got Server path" + event.getpath () + "which is
                    Too short for chroot path "+ Chrootpath);
                }} Watchedevent we = new Watchedevent (event); If(Log.isdebugenabled ()) {Log.debug ("Got" + We + "for SessionID 0x" + long.tohexstring (SessionID
                )); } eventthread.queueevent (We);
            The final event execution relies on the Eventthread thread, first in the Eventthread internal queue return; }//If SASL authentication is currently in progress, construct and//Send a response packet Imm
            ediately, rather than queuing A//response as with other packets.
        ....
        }
 ....
}
client-side access to watchedevent processing

The Eventthread Asynchronous thread run () function is as follows:

Class Eventthread extends Thread {private final linkedblockingqueue<object> waitingevents = new

        Linkedblockingqueue<object> ();
              @Override public void Run () {try {isrunning = true;
                 while (true) {Object event = Waitingevents.take ();
                 if (event = = Eventofdeath) {waskilled = true;
                 } else {processevent (event); } if (waskilled) synchronized (waitingevents) {if (Waitingeve
                          Nts.isempty ()) {isrunning = false;
                       Break }}}} catch (Interruptedexception e) {log.error ("Event Threa
           D exiting due to interruption ", e);
        } log.info ("Eventthread shut Down"); }
        ....
}
Server-Side

Server side, all the Znode node data additions and deletions, will trigger the event. Datatree Trigger Watcher entry

Now let's take the example of modifying Znode data

 file: Datatree.java public Stat setData (String path, byte data[], int version, Long Zxid,
        Long time) throws Keeperexception.nonodeexception {stat s = new Stat ();
        DataNode n = nodes.get (path);
        if (n = = null) {throw new keeperexception.nonodeexception ();
        } byte lastdata[] = null;
            Synchronized (n) {lastdata = N.data;
            N.data = data;
            N.stat.setmtime (time);
            N.stat.setmzxid (ZXID);
            N.stat.setversion (version);
        N.copystat (s);
        }//Now update if the path was in a quota subtree.
        String Lastprefix; if (Lastprefix = Getmaxprefixwithquota (path)) = null) {this.updatebytes (lastprefix, (data = = null? 0:data.l
        Ength)-(Lastdata = = null? 0:lastdata.length));
        } datawatches.triggerwatch (path, eventtype.nodedatachanged);
    return s; }

At last, call Datawatchers.triggerwatch (path, eventtype.nodedatachanged) to watcher callback to the node of the path path.

Files: Watchmanager.java public set<watcher> triggerwatch (String path, EventType type, set<watcher> supress) {
        Watchedevent e = new Watchedevent (type, keeperstate.syncconnected, path);
        Hashset<watcher> watchers;
            Synchronized (this) {watchers = Watchtable.remove (path); if (watchers = = NULL | | watchers.isempty ()) {if (log.istraceenabled ()) {ZooTrace.log  Tracemessage (LOG, Zootrace.event_delivery_trace_mask, "No watchers
                For "+ path");
            } return null;
                } for (Watcher w:watchers) {hashset<string> paths = Watch2paths.get (w);
                if (paths! = null) {paths.remove (path); }}} for (Watcher w:watchers) {//Here's watcher W actually the server Proxy client watch object, for NIOSERVERCNX
     Class N       if (supress! = null && supress.contains (W)) {continue;
        } w.process (e);
    } return watchers; }
NIOSERVERCNXN Proxy watcher for data communication

First, the next nioservercnxn, which is the client and server to communicate the package class, contains the socket connection input, OutputStream, is derived from the NIO selectedkey input output.

Another important function of NIOSERVERCNXN, which enabled him to implement the Watcher interface, was to complete the agent for the client watcher.

File: Nioservercnxn

@Override
    synchronized public void process (Watchedevent event) {
        Replyheader h = new Replyheader ( -1, -1l, 0); Note here that XID is 1
        if (log.istraceenabled ()) {
            zootrace.logtracemessage (LOG, Zootrace.event_delivery_trace_mask ,
                                     "Deliver event" + Event + "to 0x"
                                     + long.tohexstring (this.sessionid) +
                                     "through" + This);
        }

        Convert watchedevent to a type so can be sent over the wire
        watcherevent e = Event.getwrapper ();

        Sendresponse (H, E, "notification"); Serialization of Watcherevent, network transport
    }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.