我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用greenlet.getcurrent()。
def __new__(cls, func, sentinel=''): if greenlet is None: raise RuntimeError('IterI requires greenlet support') stream = object.__new__(cls) stream._parent = greenlet.getcurrent() stream._buffer = [] stream.closed = False stream.sentinel = sentinel stream.pos = 0 def run(): func(stream) stream.close() g = greenlet.greenlet(run, stream._parent) while 1: rv = g.switch() if not rv: return yield rv[0]
def wait(self, timeout_seconds=None): current = greenlet.getcurrent() parent = current.parent assert parent is not None, "Should be on child greenlet" if not self._flag: self._waiters.append(current) def on_timeout(): # Called from IOLoop on main greenlet. self._waiters.remove(current) self._timeouts.remove(timeout) current.switch() if timeout_seconds is not None: timeout = self.io_loop.add_timeout( datetime.timedelta(seconds=timeout_seconds), on_timeout) self._timeouts.add(timeout) parent.switch()
def refresh(self): assert greenlet.getcurrent().parent is not None,\ "Should be on child greenlet" try: self.rsc.refresh() except pymongo.errors.AutoReconnect: pass # RSC has been collected or there # was an unexpected error. except: return finally: # Switch to greenlets blocked in wait_for_refresh(). self.refreshed.set() self.timeout_obj = self.io_loop.add_timeout( time.time() + self._refresh_interval, self.async_refresh)
def __del__(self): # This MotorCursor is deleted on whatever greenlet does the last # decref, or (if it's referenced from a cycle) whichever is current # when the GC kicks in. We may need to send the server a killCursors # message, but in Motor only direct children of the main greenlet can # do I/O. First, do a quick check whether the cursor is still alive on # the server: if self.cursor_id and self.alive: if greenlet.getcurrent().parent is not None: # We're on a child greenlet, send the message. self.delegate.close() else: # We're on the main greenlet, start the operation on a child. self.close() # Paper over some differences between PyMongo Cursor and CommandCursor.
def resolve(self, host, port, family): """Return list of (family, address) pairs.""" child_gr = greenlet.getcurrent() main = child_gr.parent assert main is not None, "Should be on child greenlet" def handler(exc_typ, exc_val, exc_tb): # If netutil.Resolver is configured to use TwistedResolver. if DomainError and issubclass(exc_typ, DomainError): exc_typ = socket.gaierror exc_val = socket.gaierror(str(exc_val)) # Depending on the resolver implementation, we could be on any # thread or greenlet. Return to the loop's thread and raise the # exception on the calling greenlet from there. self.io_loop.add_callback(functools.partial( child_gr.throw, exc_typ, exc_val, exc_tb)) return True # Don't propagate the exception. with stack_context.ExceptionStackContext(handler): self.resolver.resolve(host, port, family, callback=child_gr.switch) return main.switch()
def test_greenlet_tracing(self): main = greenlet.getcurrent() actions = [] def trace(*args): actions.append(args) def dummy(): pass def dummyexc(): raise SomeError() oldtrace = greenlet.settrace(trace) try: g1 = greenlet.greenlet(dummy) g1.switch() g2 = greenlet.greenlet(dummyexc) self.assertRaises(SomeError, g2.switch) finally: greenlet.settrace(oldtrace) self.assertEqual(actions, [ ('switch', (main, g1)), ('switch', (g1, main)), ('switch', (main, g2)), ('throw', (g2, main)), ])
def test_setparent(self): def foo(): def bar(): greenlet.getcurrent().parent.switch() # This final switch should go back to the main greenlet, since # the test_setparent() function in the C extension should have # reparented this greenlet. greenlet.getcurrent().parent.switch() raise AssertionError("Should never have reached this code") child = greenlet.greenlet(bar) child.switch() greenlet.getcurrent().parent.switch(child) greenlet.getcurrent().parent.throw( AssertionError("Should never reach this code")) foo_child = greenlet.greenlet(foo).switch() self.assertEqual(None, _test_extension.test_setparent(foo_child))
def test_throw(self): seen = [] def foo(): try: greenlet.getcurrent().parent.switch() except ValueError: seen.append(sys.exc_info()[1]) except greenlet.GreenletExit: raise AssertionError g = greenlet.greenlet(foo) g.switch() _test_extension.test_throw(g) self.assertEqual(len(seen), 1) self.assertTrue( isinstance(seen[0], ValueError), "ValueError was not raised in foo()") self.assertEqual( str(seen[0]), 'take that sucka!', "message doesn't match")
def test_threaded_leak(self): gg = [] def worker(): # only main greenlet present gg.append(weakref.ref(greenlet.getcurrent())) for i in range(2): t = threading.Thread(target=worker) t.start() t.join() del t greenlet.getcurrent() # update ts_current self.recycle_threads() greenlet.getcurrent() # update ts_current gc.collect() greenlet.getcurrent() # update ts_current for g in gg: self.assertTrue(g() is None)
def handle_system_error(self, type, value): current = getcurrent() if current is self or current is self.parent or self.loop is None: self.parent.throw(type, value) else: # in case system error was handled and life goes on # switch back to this greenlet as well cb = None try: cb = self.loop.run_callback(current.switch) except: traceback.print_exc() try: self.parent.throw(type, value) finally: if cb is not None: cb.stop()
def run(self): """ Entry-point to running the loop. This method is called automatically when the hub greenlet is scheduled; do not call it directly. :raises LoopExit: If the loop finishes running. This means that there are no other scheduled greenlets, and no active watchers or servers. In some situations, this indicates a programming error. """ assert self is getcurrent(), 'Do not call Hub.run() directly' while True: loop = self.loop loop.error_handler = self try: loop.run() finally: loop.error_handler = None # break the refcount cycle self.parent.throw(LoopExit('This operation would block forever', self)) # this function must never return, as it will cause switch() in the parent greenlet # to return an unexpected value # It is still possible to kill this greenlet with throw. However, in that case # switching to it is no longer safe, as switch will return immediatelly
def handle_system_error(self, type, value): current = getcurrent() if current is self or current is self.parent or self.loop is None: self.parent.throw(type, value) else: # in case system error was handled and life goes on # switch back to this greenlet as well cb = None try: cb = self.loop.run_callback(current.switch) except: # pylint:disable=bare-except traceback.print_exc(file=self.exception_stream) try: self.parent.throw(type, value) finally: if cb is not None: cb.stop()
def synclize(func): coro = coroutine(func) @wraps(func) def _sync_call(*args, **kwargs): child_gr = greenlet.getcurrent() main = child_gr.parent assert main, "only run in child greenlet" def callback(future): if future.exc_info(): child_gr.throw(*future.exc_info()) elif future.exception(): child_gr.throw(future.exception()) else: child_gr.switch(future.result()) IOLoop.current().add_future(coro(*args, **kwargs), callback) return main.switch() return _sync_call