예제 #1
0
    def __init__(self, host, port=None, ws=True, stop_event=None):
        threading.Thread.__init__(self)
        
        if not host[-1] == "]" and host.rfind(":") > -1:
            # Not a literal IPv6 address and a port is given as part of the hostname
            pos = host.rfind(":")
            if pos > -1:
                port = int(host[pos+1:])
                host = host[:pos]

        self.log = MyLog().log

        # Synchronization
        self._client_lock = threading.Lock()
        self._stop_event = stop_event if stop_event != None else threading.Event()
        # Data structures
        self._cache = {} # msvid -> msv_data
        self._msv_handlers = []
        self._set_handlers = []
        # Timeout Manager
        self._tm = timeouts.TimeoutManager(stop_event=self._stop_event)
        # Server Clock Estimator
        self._clock = ServerClockEstimator()
        # Backoffticker
        self._ticker = BackoffTicker(self._tm, self._ontick)
        # Request management
        self._request_counter = 0
        self._pending_requests = {} # reqid -> (event, result) 
        # Connection to MsvServer
        if ws == True:
            self._conn = connection.WSConnection()
            if not port:
                self._serv_addr = (host, messages.CLIENT_ACCEPT_PORT)
            else:
                self._serv_addr = (host, port)
        else:
            self._conn = connection.Connection()
            if not port:
                self._serv_addr = (host, messages.FRONTEND_ACCEPT_PORT)
            else:
                self._serv_addr = (host, port)

        self._isReady = threading.Event()
예제 #2
0
class Client(threading.Thread):

    def __init__(self, host, port=None, ws=True, stop_event=None):
        threading.Thread.__init__(self)
        
        if not host[-1] == "]" and host.rfind(":") > -1:
            # Not a literal IPv6 address and a port is given as part of the hostname
            pos = host.rfind(":")
            if pos > -1:
                port = int(host[pos+1:])
                host = host[:pos]

        self.log = MyLog().log

        # Synchronization
        self._client_lock = threading.Lock()
        self._stop_event = stop_event if stop_event != None else threading.Event()
        # Data structures
        self._cache = {} # msvid -> msv_data
        self._msv_handlers = []
        self._set_handlers = []
        # Timeout Manager
        self._tm = timeouts.TimeoutManager(stop_event=self._stop_event)
        # Server Clock Estimator
        self._clock = ServerClockEstimator()
        # Backoffticker
        self._ticker = BackoffTicker(self._tm, self._ontick)
        # Request management
        self._request_counter = 0
        self._pending_requests = {} # reqid -> (event, result) 
        # Connection to MsvServer
        if ws == True:
            self._conn = connection.WSConnection()
            if not port:
                self._serv_addr = (host, messages.CLIENT_ACCEPT_PORT)
            else:
                self._serv_addr = (host, port)
        else:
            self._conn = connection.Connection()
            if not port:
                self._serv_addr = (host, messages.FRONTEND_ACCEPT_PORT)
            else:
                self._serv_addr = (host, port)

        self._isReady = threading.Event()
        
    def isReady(self):
        return self._isReady.isSet()

    def waitForReady(self, timeout):
        return self._isReady.wait(timeout)

    def isConnected(self):
        """Added by Ingar to check if client is ready for operation.
        TODO: this should NOT be different from isReady
        """
        return self._conn and self._conn.is_connected()

    def stop(self):
        """Request that the client (main loop) stops"""
        self._stop_event.set()

    def run(self):
        """Main loop"""
        self._tm.start()
        #self._conn.connect(self._serv_addr)
        self._ticker.start()
        self._isReady.set()
        while not self._stop_event.is_set():
            if not self._conn.is_connected():
                try:
                    self._conn.connect(self._serv_addr)
                    
                    # Get whatever msvs we were already monitoring
                    self.log.debug("Reconnected, restoring subscriptions")
                    self.get(self._cache.keys())
                    
                except:
                    self.log.exception("Failed to connect, retrying later")
                    time.sleep(5)
                continue

            try:
                data = self._conn.get(1.0)
            except:
                self.log.exception("Failed to read, trying to reconnect")
                self._conn.close()
                continue

            if data != None:
                try:
                    msg = json.loads(data)
                    self._onmessage(msg)
                except ValueError:
                    self.log.exception("Bad message '%s'"%data)
                    continue
        # Cleanup
        self._conn.close()

    def _onmessage(self, msg):
        """Receive message from connection"""

        if msg['cmd'] == MsvCmd.PONG:
            cs, ss = msg['data']
            cr = time.time()
            self._clock.add_sample(cs, ss, cr)
            return
        
        if msg['type'] == MsgType.RESPONSE: # all responses except PONG

            # Update Msv Cache
            if msg['cmd'] in [MsvCmd.GET, MsvCmd.CREATE]:
                for msv_data in msg['data']:
                    self._cache[msv_data['msvid']] = msv_data

            try:
                # Hand over response to requesting client
                self._onresponse(msg)
            except Exception, e:
                print "MSV CLIENT ERROR, calling onresponse:",e
                traceback.print_exc()
                
            # Notify clients of set changes
            if msg['cmd'] in [MsvCmd.GET, MsvCmd.CREATE]:
                msvid_list = [x['msvid'] for x in msg['data']]
                for handler in self._set_handlers:
                    try:
                        handler(msvid_list, [])
                    except Exception, e:
                        print "MSV CLIENT ERROR on handler %s: %s"%(handler, e)
                        traceback.print_exc()
            return