def update(self, spin): """ This method is called on READ to recv data from the socket. Events: LOAD, CLOSE, RECV_ERR """ try: # Receive self.SIZE bytes at most. data = spin.recv(self.SIZE) # If data == '' then it is over. if not data: spawn(spin, CLOSE, '') # Otherwise it arose data. else: spawn(spin, LOAD, data) except socket.error as excpt: # The excpt.args[0] contains the socket # status. err = excpt.args[0] # If it is the case of the connection being closed # we spawn CLOSE with the motive. if err in CLOSE_ERR_CODE: spawn(spin, CLOSE, err) else: # In case of error. spawn(spin, RECV_ERR, err) debug()
def lose(spin): spin.destroy() try: spin.close() except Exception as excpt: err = excpt.args[0] spawn(spin, CLOSE_ERR, err) debug()
def update(self, device): try: data = self.queue.popleft() device.write(data) except IOError as excpt: err = excpt.args[0] spawn(device, CLOSE, err) debug() except IndexError: # If the queue is empty we no more need # the WRITE event. zmap(device, WRITE, self.update) # It is important to know when all data was # fully sent. It spawns DUMPED when the queue # is empty. spawn(device, DUMPED)
def update(self, device): try: # It might happen of data having length lower than SIZE. data = device.read(self.SIZE) except IOError as excpt: # When an exception occurs it deliveries the exception err. # It as well spawns CLOSE. err = excpt.args[0] spawn(device, CLOSE, err) # This is interesting so we can know what is going on. debug() else: if not data: spawn(device, CLOSE, '') # The event carrying the data. # This is interesting sharing the LOAD event # since we can use sub protocols for Stdout. spawn(device, LOAD, data)
def update(self, spin): """ This method is called on WRITE to send data. It attempts to optmize the job of sending bytes by using buffer. The algorithm is explained in the class doc. Events: DUMPED, CLOSE, SEND_ERR See help(Stdin). """ try: if not self.data: self.data = self.queue.popleft() # As we are in non blocking mode a call to send # doesn't block. We just need to know the amount # of bytes sent. size = spin.send(self.data) # We move the pointer size bytes ahead. self.data = buffer(self.data, size) except socket.error as excpt: err = excpt.args[0] # The err value contains the socket status error code. # It is passed with either CLOSE or SEND_ERR so # users of this protocol can know what happened # exactly with the call to send. if err in CLOSE_ERR_CODE: spawn(spin, CLOSE, err) else: spawn(spin, SEND_ERR, err) debug() except IndexError: # If the queue is empty we no more need # the WRITE event. zmap(spin, WRITE, self.update) # It is important to know when all data was # fully sent. It spawns DUMPED when the queue # is empty. spawn(spin, DUMPED)
def update(self, spin): # Calls repeatedly accept to improve efficience. while True: try: sock, addr = spin.accept() # Instantiate a new Spin and spreads it. # Since it is connected is_on=True new = Spin(sock) spawn(spin, ACCEPT, new) except socket.error as excpt: # If there is no client accept throws # an exception that is spreaded too. err = excpt.args[0] if not err in ACCEPT_ERR_CODE: # It spawns ACCEPT_ERR just if the socket # it isn't a peculiar set of conditions. # As we are calling accpet inside a while # we would have continously EAGAIN, EWOULDBLOCK etc. spawn(spin, ACCEPT_ERR, err) debug() else: break