def tearDown(self): if not IOLoop.initialized() or self.io_loop is not IOLoop.instance(): # Try to clean up any file descriptors left open in the ioloop. # This avoids leaks, especially when tests are run repeatedly # in the same process with autoreload (because curl does not # set FD_CLOEXEC on its file descriptors) self.io_loop.close(all_fds=True) super(AsyncTestCase, self).tearDown()
def tearDown(self): if (not IOLoop.initialized() or self.io_loop is not IOLoop.instance()): # Try to clean up any file descriptors left open in the ioloop. # This avoids leaks, especially when tests are run repeatedly # in the same process with autoreload (because curl does not # set FD_CLOEXEC on its file descriptors) self.io_loop.close(all_fds=True) super(AsyncTestCase, self).tearDown()
def setUp(self): self._reactor = TornadoReactor(IOLoop()) r, w = os.pipe() self._set_nonblocking(r) self._set_nonblocking(w) set_close_exec(r) set_close_exec(w) self._p1 = os.fdopen(r, "rb", 0) self._p2 = os.fdopen(w, "wb", 0)
def run(): app = Application() port = random.randrange(options.min_port, options.max_port) app.listen(port, address='127.0.0.1') signal.signal(signal.SIGCHLD, handle_sigchld) args = ["ab"] args.extend(["-n", str(options.n)]) args.extend(["-c", str(options.c)]) if options.keepalive: args.append("-k") if options.quiet: # just stops the progress messages printed to stderr args.append("-q") args.append("http://127.0.0.1:%d/" % port) subprocess.Popen(args) IOLoop.instance().start() IOLoop.instance().close() del IOLoop._instance assert not IOLoop.initialized()
def add_sockets(self, sockets): """Makes this server start accepting connections on the given sockets. The ``sockets`` parameter is a list of socket objects such as those returned by `bind_sockets`. `add_sockets` is typically used in combination with that method and `anzu.process.fork_processes` to provide greater control over the initialization of a multi-process server. """ if self.io_loop is None: self.io_loop = IOLoop.instance() for sock in sockets: self._sockets[sock.fileno()] = sock add_accept_handler(sock, self._handle_connection, io_loop=self.io_loop)
def add_accept_handler(sock, callback, io_loop=None): """Adds an ``IOLoop`` event handler to accept new connections on ``sock``. When a connection is accepted, ``callback(connection, address)`` will be run (``connection`` is a socket object, and ``address`` is the address of the other end of the connection). Note that this signature is different from the ``callback(fd, events)`` signature used for ``IOLoop`` handlers. """ if io_loop is None: io_loop = IOLoop.instance() def accept_handler(fd, events): while True: try: connection, address = sock.accept() except socket.error, e: if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): return raise callback(connection, address)
class HTTPClient(object): """A blocking HTTP client. This interface is provided for convenience and testing; most applications that are running an IOLoop will want to use `AsyncHTTPClient` instead. Typical usage looks like this:: http_client = httpclient.HTTPClient() try: response = http_client.fetch("http://www.google.com/") print response.body except httpclient.HTTPError, e: print "Error:", e """ def __init__(self): self._io_loop = IOLoop() self._async_client = AsyncHTTPClient(self._io_loop) self._response = None self._closed = False def __del__(self): self.close() def close(self): """Closes the HTTPClient, freeing any resources used.""" if not self._closed: self._async_client.close() self._io_loop.close() self._closed = True def fetch(self, request, **kwargs): """Executes a request, returning an `HTTPResponse`. The request may be either a string URL or an `HTTPRequest` object. If it is a string, we construct an `HTTPRequest` using any additional kwargs: ``HTTPRequest(request, **kwargs)`` If an error occurs during the fetch, we raise an `HTTPError`. """ def callback(response): self._response = response self._io_loop.stop() self._async_client.fetch(request, callback, **kwargs) self._io_loop.start() response = self._response self._response = None response.rethrow() return response
def __new__(cls, io_loop=None, max_clients=10, force_instance=False, **kwargs): io_loop = io_loop or IOLoop.instance() if cls is AsyncHTTPClient: if cls._impl_class is None: from anzu.simple_httpclient import SimpleAsyncHTTPClient AsyncHTTPClient._impl_class = SimpleAsyncHTTPClient impl = AsyncHTTPClient._impl_class else: impl = cls if io_loop in impl._async_clients() and not force_instance: return impl._async_clients()[io_loop] else: instance = super(AsyncHTTPClient, cls).__new__(impl) args = {} if cls._impl_kwargs: args.update(cls._impl_kwargs) args.update(kwargs) instance.initialize(io_loop, max_clients, **args) if not force_instance: impl._async_clients()[io_loop] = instance return instance
def handle_sigchld(sig, frame): IOLoop.instance().add_callback(IOLoop.instance().stop)
def test_multi_process(self): self.assertFalse(IOLoop.initialized()) port = get_unused_port() def get_url(path): return "http://127.0.0.1:%d%s" % (port, path) sockets = bind_sockets(port, "127.0.0.1") # ensure that none of these processes live too long signal.alarm(5) # master process id = fork_processes(3, max_restarts=3) if id is None: # back in the master process; everything worked! self.assertTrue(task_id() is None) for sock in sockets: sock.close() signal.alarm(0) return signal.alarm(5) # child process try: if id in (0, 1): signal.alarm(5) self.assertEqual(id, task_id()) server = HTTPServer(self.get_app()) server.add_sockets(sockets) IOLoop.instance().start() elif id == 2: signal.alarm(5) self.assertEqual(id, task_id()) for sock in sockets: sock.close() client = HTTPClient() def fetch(url, fail_ok=False): try: return client.fetch(get_url(url)) except HTTPError, e: if not (fail_ok and e.code == 599): raise # Make two processes exit abnormally fetch("/?exit=2", fail_ok=True) fetch("/?exit=3", fail_ok=True) # They've been restarted, so a new fetch will work int(fetch("/").body) # Now the same with signals # Disabled because on the mac a process dying with a signal # can trigger an "Application exited abnormally; send error # report to Apple?" prompt. #fetch("/?signal=%d" % signal.SIGTERM, fail_ok=True) #fetch("/?signal=%d" % signal.SIGABRT, fail_ok=True) #int(fetch("/").body) # Now kill them normally so they won't be restarted fetch("/?exit=0", fail_ok=True) # One process left; watch it's pid change pid = int(fetch("/").body) fetch("/?exit=4", fail_ok=True) pid2 = int(fetch("/").body) self.assertNotEqual(pid, pid2) # Kill the last one so we shut down cleanly fetch("/?exit=0", fail_ok=True) os._exit(0) except Exception: logging.error("exception in child process %d", id, exc_info=True) raise
def __init__(self): self._io_loop = IOLoop() self._async_client = AsyncHTTPClient(self._io_loop) self._response = None self._closed = False
def get_new_ioloop(self): '''Creates a new IOLoop for this test. May be overridden in subclasses for tests that require a specific IOLoop (usually the singleton). ''' return IOLoop()
def setUp(self): self._reactor = TornadoReactor(IOLoop())
def setUp(self): self._reactor = TornadoReactor(IOLoop()) self._mainThread = thread.get_ident()