def run(self): acceptors = [] for sock in self.sockets: gsock = gsocket(sock.FAMILY, socket.SOCK_STREAM, fileno=sock.fileno()) gsock.setblocking(1) hfun = partial(self.handle, gsock) acceptor = guv.spawn(_guv_serve, gsock, hfun, self.worker_connections) acceptors.append(acceptor) guv.gyield() try: while self.alive: self.notify() guv.sleep(self.timeout / 2) except (KeyboardInterrupt, SystemExit): log.debug('KeyboardInterrupt, exiting') self.notify() try: with guv.Timeout(self.cfg.graceful_timeout) as t: for a in acceptors: a.kill(guv.StopServe()) for a in acceptors: a.wait() except guv.Timeout as te: if te != t: raise for a in acceptors: a.kill() log.debug('GuvWorker exited')
def test_condition(self): print() cv = threading.Condition() items = [] def produce(): print('start produce()') with cv: for i in range(10): items.append(i) print('yield from produce()') gyield() print('notify') cv.notify() print('done produce()') def consume(): print('start consume()') with cv: while not len(items) == 10: print('wait ({}/{})'.format(len(items), 10)) cv.wait() print('items: {}'.format(len(items))) print('done consume()') spawn(produce) spawn(consume) print('switch to hub') gyield(False) print('done test')
def f(): greenlet_ids[1] = greenlet.getcurrent() debug(2) print('t: 1') gyield() print('t: 2') gyield() print('t: 3')
def handle(self, server_sock, client_sock, addr): """Handle client connection The client may send one or more requests. """ req = None try: parser = http.RequestParser(self.cfg, client_sock) try: server_name = server_sock.getsockname() if not self.cfg.keepalive: req = next(parser) self.handle_request(server_name, req, client_sock, addr) else: # keepalive loop while True: req = None with self.timeout_ctx(): req = next(parser) if not req: break self.handle_request(server_name, req, client_sock, addr) gyield() except http.errors.NoMoreData as e: self.log.debug("Ignored premature client disconnection. %s", e) except StopIteration as e: self.log.debug("Closing connection. %s", e) except ssl.SSLError: exc_info = sys.exc_info() # pass to next try-except level reraise(exc_info[0], exc_info[1], exc_info[2]) except socket.error: exc_info = sys.exc_info() # pass to next try-except level reraise(exc_info[0], exc_info[1], exc_info[2]) except Exception as e: self.handle_error(req, client_sock, addr, e) except ssl.SSLError as e: if get_errno(e) == ssl.SSL_ERROR_EOF: self.log.debug("ssl connection closed") client_sock.close() else: self.log.debug("Error processing SSL request.") self.handle_error(req, client_sock, addr, e) except socket.error as e: if get_errno(e) not in BROKEN_SOCK: self.log.exception("Socket error processing request.") else: if get_errno(e) == errno.ECONNRESET: self.log.debug("Ignoring connection reset") else: self.log.debug("Ignoring EPIPE") except Exception as e: self.handle_error(req, client_sock, addr, e) finally: util.close(client_sock)
def produce(): print('start produce()') with cv: for i in range(10): items.append(i) print('yield from produce()') gyield() print('notify') cv.notify() print('done produce()')
def handle_http(sock, addr): """A more complicated handler which detects HTTP headers """ def recv_request(p): while True: data = sock.recv(8192) if not data: return False nb = len(data) nparsed = p.execute(data, nb) assert nparsed == nb if USING_PYPARSER and p.is_headers_complete(): h = p.get_headers() if not (h.get('content-length') or h.get('transfer-length')): # pass length=0 to signal end of body # TODO: pyparser requires this, but not the C parser for some reason p.execute(data, 0) return True if p.is_message_complete(): return True # main request loop while True: p = HttpParser() if not recv_request(p): break h = p.get_headers() ka = p.should_keep_alive() h_connection = 'keep-alive' if ka else 'close' resp = create_response('Hello, world!', {'Connection': h_connection}) sock.sendall(resp) if not ka: break else: # we should keep-alive, but yield to drastically improve overall request/response # latency gyield() sock.close()
def main(): greenlet_ids[0] = greenlet.getcurrent() debug(1) t = threading.Thread(target=f) t.start() gyield() # `t` doesn't actually run until we yield debug(3) print('m: 1') gyield() print('m: 2') gyield() print('m: 3') t.join()