def hub_blocking_detection(state=False, resolution=1): """ Toggles whether Evy makes an effort to detect blocking behavior in an application. It does this by telling the kernel to raise a SIGALARM after a short timeout, and clearing the timeout every time the hub greenlet is resumed. Therefore, any code that runs for a long time without yielding to the hub will get interrupted by the blocking detector (don't use it in production!). The *resolution* argument governs how long the SIGALARM timeout waits in seconds. If on Python 2.6 or later, the implementation uses :func:`signal.setitimer` and can be specified as a floating-point value. On 2.5 or earlier, 1 second is the minimum. The shorter the resolution, the greater the chance of false positives. """ from evy import hubs assert resolution > 0 hubs.get_hub().debug_blocking = state hubs.get_hub().debug_blocking_resolution = resolution if not state: hubs.get_hub().block_detect_post()
def acquire (self, blocking = True): """Acquire a semaphore. When invoked without arguments: if the internal counter is larger than zero on entry, decrement it by one and return immediately. If it is zero on entry, block, waiting until some other thread has called release() to make it larger than zero. This is done with proper interlocking so that if multiple acquire() calls are blocked, release() will wake exactly one of them up. The implementation may pick one at random, so the order in which blocked threads are awakened should not be relied on. There is no return value in this case. When invoked with blocking set to true, do the same thing as when called without arguments, and return true. When invoked with blocking set to false, do not block. If a call without an argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true.""" if not blocking and self.locked(): return False if self.counter <= 0: self._waiters.add(greenthread.getcurrent()) try: while self.counter <= 0: hubs.get_hub().switch() finally: self._waiters.discard(greenthread.getcurrent()) self.counter -= 1 return True
def hub_blocking_detection (state = False, resolution = 1): """ Toggles whether Evy makes an effort to detect blocking behavior in an application. It does this by telling the kernel to raise a SIGALARM after a short timeout, and clearing the timeout every time the hub greenlet is resumed. Therefore, any code that runs for a long time without yielding to the hub will get interrupted by the blocking detector (don't use it in production!). The *resolution* argument governs how long the SIGALARM timeout waits in seconds. If on Python 2.6 or later, the implementation uses :func:`signal.setitimer` and can be specified as a floating-point value. On 2.5 or earlier, 1 second is the minimum. The shorter the resolution, the greater the chance of false positives. """ from evy import hubs assert resolution > 0 hubs.get_hub().debug_blocking = state hubs.get_hub().debug_blocking_resolution = resolution if not state: hubs.get_hub().block_detect_post()
def close(self): _Socket.close(self) if self._evy_listener is not None: hubs.get_hub().remove(self._evy_listener) self._evy_listener = None # wake any blocked threads self._evy_send_event.wake() self._evy_recv_event.wake()
def close (self): _Socket.close(self) if self._evy_listener is not None: hubs.get_hub().remove(self._evy_listener) self._evy_listener = None # wake any blocked threads self._evy_send_event.wake() self._evy_recv_event.wake()
def test_cancel_immediate(self): hub = hubs.get_hub() stimers = hub.timers_count for i in xrange(2000): t = hubs.get_hub().schedule_call_global(60, noop) t.cancel() # there should be fewer than 1000 new timers and canceled self.assert_less_than_equal(hub.timers_count, 1000 + stimers)
def test_cancel_immediate (self): hub = hubs.get_hub() stimers = hub.timers_count for i in xrange(2000): t = hubs.get_hub().schedule_call_global(60, noop) t.cancel() # there should be fewer than 1000 new timers and canceled self.assert_less_than_equal(hub.timers_count, 1000 + stimers)
def hub_listener_stacks (state = False): """Toggles whether or not the hub records the stack when clients register listeners on file descriptors. This can be useful when trying to figure out what the hub is up to at any given moment. To inspect the stacks of the current listeners, call :func:`format_hub_listeners` at critical junctures in the application logic. """ from evy import hubs hubs.get_hub().set_debug_listeners(state)
def hub_exceptions (state = True): """Toggles whether the hub prints exceptions that are raised from its timers. This can be useful to see how greenthreads are terminating. """ from evy import hubs hubs.get_hub().set_timer_exceptions(state) from evy.green import pools as greenpool greenpool.DEBUG = state
def hub_exceptions(state=True): """Toggles whether the hub prints exceptions that are raised from its timers. This can be useful to see how greenthreads are terminating. """ from evy import hubs hubs.get_hub().set_timer_exceptions(state) from evy.green import pools as greenpool greenpool.DEBUG = state
def hub_listener_stacks(state=False): """Toggles whether or not the hub records the stack when clients register listeners on file descriptors. This can be useful when trying to figure out what the hub is up to at any given moment. To inspect the stacks of the current listeners, call :func:`format_hub_listeners` at critical junctures in the application logic. """ from evy import hubs hubs.get_hub().set_debug_listeners(state)
def release (self, blocking = True): """Release a semaphore, incrementing the internal counter by one. When it was zero on entry and another thread is waiting for it to become larger than zero again, wake up that thread. The *blocking* argument is for consistency with CappedSemaphore and is ignored""" self.counter += 1 if self._waiters: hubs.get_hub().run_callback(self._do_acquire) return True
def cancel(self): """ Prevent this idle from being called. If the callback has already been called or canceled, has no effect. """ if not self.called: self.called = True get_hub()._callback_canceled(self) try: del self.callback except AttributeError: pass
def cancel(self): """ Prevent this timer from being called. If the timer has already been called or canceled, has no effect. """ if not self.called: self.called = True get_hub()._timer_canceled(self) try: del self.callback except AttributeError: pass
def schedule(self): """ Schedule this timer to run in the current loop. """ self.called = False self.scheduled_time = get_hub().add_timer(self) return self
def close(self): """ Close the TCP socket :return: None """ try: if self.uv_handle: ## remove some TCP-specific stuff self._did_listen = None self._did_accept = None if not self.uv_handle.closed: def closed_callback(*args): pass self.uv_handle.close(closed_callback) elif self.uv_fd: self.uv_fd.close() finally: ## we must remove all pollers on this socket hub = self.uv_hub if self.uv_hub else get_hub() hub.remove_descriptor(self.fileno(), skip_callbacks=True) self.uv_handle = None self.uv_fd = None # This function should not reference any globals. See issue #808164. for method in _closed_delegate_methods: setattr(self, method, _closed_dummy)
def close (self): """ Close the TCP socket :return: None """ try: if self.uv_handle: ## remove some TCP-specific stuff self._did_listen = None self._did_accept = None if not self.uv_handle.closed: def closed_callback (*args): pass self.uv_handle.close(closed_callback) elif self.uv_fd: self.uv_fd.close() finally: ## we must remove all pollers on this socket hub = self.uv_hub if self.uv_hub else get_hub() hub.remove_descriptor(self.fileno(), skip_callbacks = True) self.uv_handle = None self.uv_fd = None # This function should not reference any globals. See issue #808164. for method in _closed_delegate_methods: setattr(self, method, _closed_dummy)
def __init__(self, fileno, persistent=False, **kw): """ Create a poller. :param fileno: the file descriptor we are going to poll :param cb: the callback to call when we have detected we can read/write from this file descriptor :param *args: the arguments to pass to cb :param **kw: the keyword arguments to pass to cb This poller will not be run unless it is scheduled in a hub by get_hub().add_poller(poller). """ if fileno < 0: raise ValueError('invalid file descriptor: %d' % (fileno)) self.fileno = fileno self.persistent = persistent self.started = False self.read_callback = kw.pop('_read_callback', None) self.write_callback = kw.pop('_write_callback', None) self.hub = weakref.proxy(kw.pop('_hub', get_hub())) self.impl = pyuv.Poll(self.hub.uv_loop, fileno) if _g_debug: import traceback, cStringIO self.traceback = cStringIO.StringIO() traceback.print_stack(file=self.traceback)
def __init__ (self, f, mode = 'r', bufsize = -1): self.uv_hub = proxy(get_hub()) if not isinstance(f, (basestring, int, file)): raise TypeError('f(ile) should be int, str, unicode or file, not %r' % f) if isinstance(f, basestring): self._path = f f = open(f, mode, 0) fileno = f.fileno() if isinstance(f, int): fileno = f self._name = "<fd:%d>" % fileno self._path = None else: fileno = _os_orig.dup(f.fileno()) self._name = self._path = f.name if f.mode != mode: raise ValueError('file.mode %r does not match mode parameter %r' % (f.mode, mode)) f.close() ## close the file provided: we keep our dupped version... assert isinstance(fileno, int) self._fileobj = _os_orig.fdopen(fileno, mode) super(GreenPipe, self).__init__(_SocketDuckForFd(fileno), mode, bufsize) set_nonblocking(self) self.softspace = 0
def __init__(self, fileno, persistent = False, **kw): """ Create a poller. :param fileno: the file descriptor we are going to poll :param cb: the callback to call when we have detected we can read/write from this file descriptor :param *args: the arguments to pass to cb :param **kw: the keyword arguments to pass to cb This poller will not be run unless it is scheduled in a hub by get_hub().add_poller(poller). """ if fileno < 0: raise ValueError('invalid file descriptor: %d' % (fileno)) self.fileno = fileno self.persistent = persistent self.started = False self.read_callback = kw.pop('_read_callback', None) self.write_callback = kw.pop('_write_callback', None) self.hub = weakref.proxy(kw.pop('_hub', get_hub())) self.impl = pyuv.Poll(self.hub.uv_loop, fileno) if _g_debug: import traceback, cStringIO self.traceback = cStringIO.StringIO() traceback.print_stack(file = self.traceback)
def check_hub (): # Clear through the descriptor queue threads.sleep(0) threads.sleep(0) hub = hubs.get_hub() for nm in 'get_readers', 'get_writers': dct = getattr(hub, nm)() assert not dct, "hub.%s not empty: %s" % (nm, dct)
def check_hub(): # Clear through the descriptor queue threads.sleep(0) threads.sleep(0) hub = hubs.get_hub() for nm in 'get_readers', 'get_writers': dct = getattr(hub, nm)() assert not dct, "hub.%s not empty: %s" % (nm, dct)
def wait (self): """Wait until switch() or throw() is called. """ assert self.greenlet is None, 'This Waiter is already used by %r' % (self.greenlet, ) self.greenlet = getcurrent() try: return get_hub().switch() finally: self.greenlet = None
def verify_hub_empty (): from evy import hubs hub = hubs.get_hub() num_readers = len(hub.get_readers()) num_writers = len(hub.get_writers()) num_timers = hub.get_timers_count() assert num_readers == 0 and num_writers == 0, "Readers: %s Writers: %s" % ( num_readers, num_writers)
def verify_hub_empty(): from evy import hubs hub = hubs.get_hub() num_readers = len(hub.get_readers()) num_writers = len(hub.get_writers()) num_timers = hub.get_timers_count() assert num_readers == 0 and num_writers == 0, "Readers: %s Writers: %s" % ( num_readers, num_writers)
def cede(): """ Yield control to another eligible coroutine. It is a cooperative yield. For example, if one is looping over a large list performing an expensive calculation without calling any socket methods, it's a good idea to call ``cede()`` occasionally; otherwise nothing else will run. """ hub = hubs.get_hub() hub.cede()
def restart_hub(): from evy import hubs hub = hubs.get_hub() hub_shortname = hub.__module__.split('.')[-1] # don't restart the pyevent hub; it's not necessary if hub_shortname != 'pyevent': hub.abort() hubs.use_hub(hub_shortname)
def restart_hub (): from evy import hubs hub = hubs.get_hub() hub_shortname = hub.__module__.split('.')[-1] # don't restart the pyevent hub; it's not necessary if hub_shortname != 'pyevent': hub.abort() hubs.use_hub(hub_shortname)
def wait(self): """Wait until switch() or throw() is called. """ assert self.greenlet is None, 'This Waiter is already used by %r' % ( self.greenlet, ) self.greenlet = getcurrent() try: return get_hub().switch() finally: self.greenlet = None
def throw (self, *throw_args): """Make greenlet calling wait() wake up (if there is a wait()). Can only be called from Hub's greenlet. """ assert getcurrent() is get_hub().greenlet, "Can only use Waiter.switch method from the mainloop" if self.greenlet is not None: try: self.greenlet.throw(*throw_args) except: traceback.print_exc()
def switch (self, value = None): """Wake up the greenlet that is calling wait() currently (if there is one). Can only be called from Hub's greenlet. """ assert getcurrent() is get_hub().greenlet, "Can only use Waiter.switch method from the mainloop" if self.greenlet is not None: try: self.greenlet.switch(value) except: traceback.print_exc()
def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None, _hub=None): """ Initialize the UV socket :param family_or_realsock: a socket descriptor or a socket family """ self.uv_fd = None self.uv_handle = None self.uv_hub = None self.uv_recv_string = '' # buffer for receiving data... if isinstance(family, (int, long)): self.uv_fd = _original_socket(family, type, proto, _sock) elif isinstance(family, GreenSocket): _sock = family self.uv_fd = _sock.uv_fd if hasattr(_sock, 'uv_hub') and _sock.uv_hub: _hub = _sock.uv_hub else: _sock = family self.uv_fd = _sock if not self.uv_hub: if _hub: self.uv_hub = _hub else: self.uv_hub = weakref.proxy(get_hub()) ## check if the socket type is supported by pyUV and we can create a pyUV socket... if not self.uv_handle: if self.type == socket.SOCK_STREAM: self.uv_handle = pyuv.TCP(self.uv_hub.uv_loop) self.uv_handle.open(self.fileno()) elif self.type == socket.SOCK_DGRAM: self.uv_handle = pyuv.UDP(self.uv_hub.uv_loop) self.uv_handle.open(self.fileno()) # import timeout from other socket, if it was there try: self._timeout = self.uv_fd.gettimeout( ) or socket.getdefaulttimeout() except AttributeError: self._timeout = socket.getdefaulttimeout() assert self.uv_fd, 'the socket descriptor must be not null' set_nonblocking(self.uv_fd) # when client calls setblocking(0) or settimeout(0) the socket must act non-blocking self.act_non_blocking = False
def select (read_list, write_list, error_list, timeout = None): # error checking like this is required by the stdlib unit tests if timeout is not None: try: timeout = float(timeout) except ValueError: raise TypeError("Expected number for timeout") hub = get_hub() t = None current = getcurrent() assert hub.greenlet is not current, 'do not call blocking functions from the mainloop' ds = {} for r in read_list: ds[get_fileno(r)] = {'read': r} for w in write_list: ds.setdefault(get_fileno(w), {})['write'] = w for e in error_list: ds.setdefault(get_fileno(e), {})['error'] = e listeners = [] def on_read (d): original = ds[get_fileno(d)]['read'] current.switch(([original], [], [])) def on_write (d): original = ds[get_fileno(d)]['write'] current.switch(([], [original], [])) def on_error (d, _err = None): original = ds[get_fileno(d)]['error'] current.switch(([], [], [original])) def on_timeout (): current.switch(([], [], [])) if timeout is not None: t = hub.schedule_call_global(timeout, on_timeout) try: for k, v in ds.iteritems(): if v.get('read'): listeners.append(hub.add(hub.READ, k, on_read)) if v.get('write'): listeners.append(hub.add(hub.WRITE, k, on_write)) try: return hub.switch() finally: for l in listeners: hub.remove(l) finally: if t is not None: t.cancel()
def select(read_list, write_list, error_list, timeout=None): # error checking like this is required by the stdlib unit tests if timeout is not None: try: timeout = float(timeout) except ValueError: raise TypeError("Expected number for timeout") hub = get_hub() t = None current = getcurrent() assert hub.greenlet is not current, 'do not call blocking functions from the mainloop' ds = {} for r in read_list: ds[get_fileno(r)] = {'read': r} for w in write_list: ds.setdefault(get_fileno(w), {})['write'] = w for e in error_list: ds.setdefault(get_fileno(e), {})['error'] = e listeners = [] def on_read(d): original = ds[get_fileno(d)]['read'] current.switch(([original], [], [])) def on_write(d): original = ds[get_fileno(d)]['write'] current.switch(([], [original], [])) def on_error(d, _err=None): original = ds[get_fileno(d)]['error'] current.switch(([], [], [original])) def on_timeout(): current.switch(([], [], [])) if timeout is not None: t = hub.schedule_call_global(timeout, on_timeout) try: for k, v in ds.iteritems(): if v.get('read'): listeners.append(hub.add(hub.READ, k, on_read)) if v.get('write'): listeners.append(hub.add(hub.WRITE, k, on_write)) try: return hub.switch() finally: for l in listeners: hub.remove(l) finally: if t is not None: t.cancel()
def test_schedule(self): hub = hubs.get_hub() # clean up the runloop, preventing side effects from previous tests # on this thread if hub.running: hub.abort() sleep(0) called = [] #t = timer.Timer(0, lambda: (called.append(True), hub.abort())) #t.schedule() # let's have a timer somewhere in the future; make sure abort() still works #hubs.get_hub().schedule_call_global(10000, lambda: (called.append(True), hub.abort())) hubs.get_hub().run_callback(lambda: (called.append(True), hub.abort())) hub.default_sleep = lambda: 0.0 hub.switch() assert called assert not hub.running
def tearDown (self): self.timer.cancel() try: hub = hubs.get_hub() num_readers = len(hub.get_readers()) num_writers = len(hub.get_writers()) assert num_readers == num_writers == 0 except AssertionError, e: print "ERROR: Hub not empty" print debug.format_hub_timers() print debug.format_hub_listeners()
def tearDown(self): self.timer.cancel() try: hub = hubs.get_hub() num_readers = len(hub.get_readers()) num_writers = len(hub.get_writers()) assert num_readers == num_writers == 0 except AssertionError, e: print "ERROR: Hub not empty" print debug.format_hub_timers() print debug.format_hub_listeners()
def test_sleep(self): # even if there was an error in the mainloop, the hub should continue to work start = time.time() sleep(DELAY) delay = time.time() - start assert delay >= DELAY * 0.9, 'sleep returned after %f seconds (was scheduled for %s)' % ( delay, DELAY) def fail(): 1 // 0 hubs.get_hub().run_callback(fail) start = time.time() sleep(DELAY) delay = time.time() - start assert delay >= DELAY * 0.9, 'sleep returned after %f seconds (was scheduled for %s)' % ( delay, DELAY)
def switch(self, value=None): """Wake up the greenlet that is calling wait() currently (if there is one). Can only be called from Hub's greenlet. """ assert getcurrent() is get_hub( ).greenlet, "Can only use Waiter.switch method from the mainloop" if self.greenlet is not None: try: self.greenlet.switch(value) except: traceback.print_exc()
def throw(self, *throw_args): """Make greenlet calling wait() wake up (if there is a wait()). Can only be called from Hub's greenlet. """ assert getcurrent() is get_hub( ).greenlet, "Can only use Waiter.switch method from the mainloop" if self.greenlet is not None: try: self.greenlet.throw(*throw_args) except: traceback.print_exc()
def test_sleep (self): # even if there was an error in the mainloop, the hub should continue to work start = time.time() sleep(DELAY) delay = time.time() - start assert delay >= DELAY * 0.9, 'sleep returned after %f seconds (was scheduled for %s)' % ( delay, DELAY) def fail (): 1 // 0 hubs.get_hub().run_callback(fail) start = time.time() sleep(DELAY) delay = time.time() - start assert delay >= DELAY * 0.9, 'sleep returned after %f seconds (was scheduled for %s)' % ( delay, DELAY)
def test_schedule (self): hub = hubs.get_hub() # clean up the runloop, preventing side effects from previous tests # on this thread if hub.running: hub.abort() sleep(0) called = [] #t = timer.Timer(0, lambda: (called.append(True), hub.abort())) #t.schedule() # let's have a timer somewhere in the future; make sure abort() still works #hubs.get_hub().schedule_call_global(10000, lambda: (called.append(True), hub.abort())) hubs.get_hub().run_callback(lambda: (called.append(True), hub.abort())) hub.default_sleep = lambda: 0.0 hub.switch() assert called assert not hub.running
def format_hub_timers(): """ Returns a formatted string of the current timers on the current hub. This can be useful in determining what's going on in the event system, especially when used in conjunction with :func:`hub_timer_stacks`. """ from evy import hubs hub = hubs.get_hub() result = ["TIMERS:"] for l in hub.timers: result.append(repr(l)) return os.linesep.join(result)
def format_hub_timers (): """ Returns a formatted string of the current timers on the current hub. This can be useful in determining what's going on in the event system, especially when used in conjunction with :func:`hub_timer_stacks`. """ from evy import hubs hub = hubs.get_hub() result = ['TIMERS:'] for l in hub.timers: result.append(repr(l)) return os.linesep.join(result)
def test_get_nowait_simple (self): from evy import hubs, queue hub = hubs.get_hub() result = [] q = queue.Queue(1) q.put(4) hub.run_callback(store_result, result, q.get_nowait) hub.run_callback(store_result, result, q.get_nowait) sleep(0) assert len(result) == 2, result assert result[0] == 4, result assert isinstance(result[1], queue.Empty), result
def test_put_nowait_simple (self): from evy import hubs, queue hub = hubs.get_hub() result = [] q = Queue(1) hub.run_callback(store_result, result, q.put_nowait, 2) hub.run_callback(store_result, result, q.put_nowait, 3) sleep(0) sleep(0) assert len(result) == 2, result assert result[0] == None, result assert isinstance(result[1], queue.Full), result
def test_put_nowait_simple(self): from evy import hubs, queue hub = hubs.get_hub() result = [] q = Queue(1) hub.run_callback(store_result, result, q.put_nowait, 2) hub.run_callback(store_result, result, q.put_nowait, 3) sleep(0) sleep(0) assert len(result) == 2, result assert result[0] == None, result assert isinstance(result[1], queue.Full), result
def test_get_nowait_simple(self): from evy import hubs, queue hub = hubs.get_hub() result = [] q = queue.Queue(1) q.put(4) hub.run_callback(store_result, result, q.get_nowait) hub.run_callback(store_result, result, q.get_nowait) sleep(0) assert len(result) == 2, result assert result[0] == 4, result assert isinstance(result[1], queue.Empty), result
def test_ordering(self): lst = [] hubs.get_hub().schedule_call_global(DELAY * 2, lst.append, 3) hubs.get_hub().schedule_call_global(DELAY, lst.append, 1) hubs.get_hub().schedule_call_global(DELAY, lst.append, 2) while len(lst) < 3: sleep(DELAY) self.assertEquals(sorted(lst), sorted([1, 2, 3]))
def test_ordering (self): lst = [] hubs.get_hub().schedule_call_global(DELAY * 2, lst.append, 3) hubs.get_hub().schedule_call_global(DELAY, lst.append, 1) hubs.get_hub().schedule_call_global(DELAY, lst.append, 2) while len(lst) < 3: sleep(DELAY) self.assertEquals(sorted(lst), sorted([1, 2, 3]))
def test_cancel_proportion (self): # if fewer than half the pending timers are canceled, it should # not clean them out hub = hubs.get_hub() uncanceled_timers = [] stimers = hub.timers_count for i in xrange(1000): # 2/3rds of new timers are uncanceled t = hubs.get_hub().schedule_call_global(60, noop) t2 = hubs.get_hub().schedule_call_global(60, noop) t3 = hubs.get_hub().schedule_call_global(60, noop) sleep() t.cancel() uncanceled_timers.append(t2) uncanceled_timers.append(t3) # 3000 new timers, plus a few extras self.assert_less_than_equal(stimers + 3000, stimers + hub.timers_count) for t in uncanceled_timers: t.cancel() sleep()
def spawn (func, *args, **kwargs): """ Create a greenthread to run ``func(*args, **kwargs)``. Returns a :class:`GreenThread` object which you can use to get the results of the call. Execution control returns immediately to the caller; the created greenthread is merely scheduled to be run at the next available opportunity. Use :func:`spawn_after` to arrange for greenthreads to be spawned after a finite delay. """ hub = hubs.get_hub() g = GreenThread(hub.greenlet) hub.run_callback(g.switch, func, args, kwargs) return g
def __init__ (self, family = socket.AF_INET, type = socket.SOCK_STREAM, proto = 0, _sock = None, _hub = None): """ Initialize the UV socket :param family_or_realsock: a socket descriptor or a socket family """ self.uv_fd = None self.uv_handle = None self.uv_hub = None self.uv_recv_string = '' # buffer for receiving data... if isinstance(family, (int, long)): self.uv_fd = _original_socket(family, type, proto, _sock) elif isinstance(family, GreenSocket): _sock = family self.uv_fd = _sock.uv_fd if hasattr(_sock, 'uv_hub') and _sock.uv_hub: _hub = _sock.uv_hub else: _sock = family self.uv_fd = _sock if not self.uv_hub: if _hub: self.uv_hub = _hub else: self.uv_hub = weakref.proxy(get_hub()) ## check if the socket type is supported by pyUV and we can create a pyUV socket... if not self.uv_handle: if self.type == socket.SOCK_STREAM: self.uv_handle = pyuv.TCP(self.uv_hub.uv_loop) self.uv_handle.open(self.fileno()) elif self.type == socket.SOCK_DGRAM: self.uv_handle = pyuv.UDP(self.uv_hub.uv_loop) self.uv_handle.open(self.fileno()) # import timeout from other socket, if it was there try: self._timeout = self.uv_fd.gettimeout() or socket.getdefaulttimeout() except AttributeError: self._timeout = socket.getdefaulttimeout() assert self.uv_fd, 'the socket descriptor must be not null' set_nonblocking(self.uv_fd) # when client calls setblocking(0) or settimeout(0) the socket must act non-blocking self.act_non_blocking = False
def test_cancel_proportion(self): # if fewer than half the pending timers are canceled, it should # not clean them out hub = hubs.get_hub() uncanceled_timers = [] stimers = hub.timers_count for i in xrange(1000): # 2/3rds of new timers are uncanceled t = hubs.get_hub().schedule_call_global(60, noop) t2 = hubs.get_hub().schedule_call_global(60, noop) t3 = hubs.get_hub().schedule_call_global(60, noop) sleep() t.cancel() uncanceled_timers.append(t2) uncanceled_timers.append(t3) # 3000 new timers, plus a few extras self.assert_less_than_equal(stimers + 3000, stimers + hub.timers_count) for t in uncanceled_timers: t.cancel() sleep()
def spawn(func, *args, **kwargs): """ Create a greenthread to run ``func(*args, **kwargs)``. Returns a :class:`GreenThread` object which you can use to get the results of the call. Execution control returns immediately to the caller; the created greenthread is merely scheduled to be run at the next available opportunity. Use :func:`spawn_after` to arrange for greenthreads to be spawned after a finite delay. """ hub = hubs.get_hub() g = GreenThread(hub.greenlet) hub.run_callback(g.switch, func, args, kwargs) return g