def closedown(self): # try our best to close the connection gracefully # assign to local to avoid race condition (self.sock # set to None by someone else calling closedown) # # This may be called more than once! sock, self.sock, self.stoprequest = self.sock, None, True if sock is not None: closeSocket(sock)
def serversocket(): """create a server socket""" serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: serv.bind(('localhost', 65432)) serv.listen(10) except Exception: pytest.skip('could not bind') yield serv closeSocket(serv)
def emit(self, event, data, handler=None): if DAEMON_EVENTS[event][0]: data = self.serializer.serialize_event(event, data) for hdlr in (handler,) if handler else self.handlers.values(): try: hdlr.event_queue.put((event, data), True, 0.1) except queue.Full: # close event socket to let the connection get # closed by the handler self.daemon.log.warning('handler %s: queue full, ' 'closing socket', hdlr.ident) closeSocket(hdlr.event_sock) closeSocket(hdlr.sock)
def _disconnect(self, why=''): self._connected = False self._startup_done.clear() if why: if self._disconnect_warnings % 10 == 0: self.log.warning(why) self._disconnect_warnings += 1 if self._socket: closeSocket(self._socket) self._socket = None # close secondary socket with self._sec_lock: if self._secsocket: closeSocket(self._secsocket) self._secsocket = None self._disconnect_action()
def test_tcpsocket(serversocket): sock = None sockargs = [('localhost:65432', 1), ('localhost', 65432), (('localhost', 65432), 1, dict(timeout=5))] for args in sockargs: try: if len(args) == 3: kwds = args[2] args = args[:2] sock = tcpSocket(*args, **kwds) else: sock = tcpSocket(*args) finally: if sock: closeSocket(sock)
def _single_request(self, tosend, sentinel=b'\n', retry=2, sync=False): """Communicate over the secondary socket.""" if not self._socket: self._disconnect('single request: no socket') if not self._socket: raise CacheError('cache not connected') if sync: # sync has to be false for lock requests, as these occur during startup self._queue.join() with self._sec_lock: if not self._secsocket: try: self._secsocket = tcpSocket(self.cache, DEFAULT_CACHE_PORT) except Exception as err: self.log.warning( 'unable to connect secondary socket ' 'to %s: %s', self.cache, err) self._secsocket = None self._disconnect('secondary socket: could not connect') raise CacheError('secondary socket could not be created') try: # write request # self.log.debug("get_explicit: sending %r", tosend) self._secsocket.sendall(to_utf8(tosend)) # give 10 seconds time to get the whole reply timeout = currenttime() + 10 # read response data = b'' while not data.endswith(sentinel): newdata = self._secsocket.recv(BUFSIZE) # blocking read if not newdata: raise socket.error('cache closed connection') if currenttime() > timeout: # do not just break, we need to reopen the socket raise socket.error('getting response took too long') data += newdata except socket.error: self.log.warning('error during cache query', exc=1) closeSocket(self._secsocket) self._secsocket = None if retry: for m in self._single_request(tosend, sentinel, retry - 1): yield m return raise lmatch = line_pattern.match mmatch = msg_pattern.match i = 0 # self.log.debug("get_explicit: data =%r", data) match = lmatch(data, i) while match: line = match.group(1) i = match.end() msgmatch = mmatch(from_utf8(line)) if not msgmatch: # ignore invalid lines continue # self.log.debug('line processed: %r', line) yield msgmatch match = lmatch(data, i)
def _close_cached_socket(self, sock): if sock is not TestCacheClient._cached_socket: closeSocket(sock)
def close(self): self.log.info('closing connection') ConnectionHandler.close(self) closeSocket(self.sock) closeSocket(self.event_sock)
def server_close(self): """Close the server socket and all client sockets.""" for handler in list(self.handlers.values()): closeSocket(handler.sock) closeSocket(handler.event_sock) closeSocket(self.socket)
def disconnect(self): closeSocket(self.sock) closeSocket(self.event_sock) self.sock = None
def doShutdown(self): if self._connection: closeSocket(self._connection)
def doReset(self): if self._connection: closeSocket(self._connection) self._connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self._connection.connect((self.host, self.port))
def _server_thread(self): self.log.info('server starting') # bind UDP broadcast socket self.log.debug('trying to bind to UDP broadcast') self._serversocket_udp = self._bind_to('', 'udp')[0] if self._serversocket_udp: self.log.info('UDP bound to broadcast') # now try to bind TCP socket, include 'MUST WORK' standalone names self.log.debug('trying to bind to %s', self.server) self._serversocket, self._boundto = self._bind_to(self.server) # one of the must have worked, otherwise continuing makes no sense if not self._serversocket and not self._serversocket_udp: self._stoprequest = True self.log.error("couldn't bind any sockets, giving up!") return if not self._boundto: self.log.warning('starting main loop only bound to UDP broadcast') else: self.log.info('TCP bound to %s:%s', self._boundto[0], self._boundto[1]) # now enter main serving loop while not self._stoprequest: # loop through connections, first to remove dead ones, # secondly to try to reconnect for addr, client in list(self._connected.items()): if not client.is_active(): # dead or stopped self.log.info('client connection %s closed', addr) client.closedown() client.join() # wait for threads to end del self._connected[addr] # now check for additional incoming connections # build list of things to check selectlist = [] if self._serversocket: selectlist.append(self._serversocket) if self._serversocket_udp: selectlist.append(self._serversocket_udp) # 3 times client-side timeout res = select.select(selectlist, [], [], CYCLETIME * 3) if not res[0]: continue # nothing to read -> continue loop # lock aginst code in self.quit with self._connectionLock: if self._stoprequest: break if self._serversocket in res[0]: # TCP connection came in conn, addr = self._serversocket.accept() addr = 'tcp://%s:%d' % addr self.log.info('new connection from %s', addr) self._connected[addr] = CacheWorker(self._attached_db, conn, name=addr, loglevel=self.loglevel) elif self._serversocket_udp in res[0]: # UDP data came in data, addr = self._serversocket_udp.recvfrom(3072) nice_addr = 'udp://%s:%d' % addr self.log.info('new connection from %s', nice_addr) self._connected[nice_addr] = CacheUDPWorker( self._attached_db, self._serversocket_udp, name=nice_addr, data=data, remoteaddr=addr, loglevel=self.loglevel) if self._serversocket: closeSocket(self._serversocket) self._serversocket = None