def updates(db, storage, registry): """ Websockets - read-write loop Here messages are broadcasted to all clients """ global messages guid = id(greenlet.getcurrent()) if request.environ.get('wsgi.websocket'): ws = request.environ['wsgi.websocket'] queue = Queue() messages[guid] = queue try: while True: # receive stuff here try: while True: mtype, ts, data = queue.get_nowait() msg = json.dumps({ 'mtype': mtype, 'ts': ts, 'data': data }) ws.send(msg) except Empty: sleep(1) finally: del messages[guid] return '' return 'I can haz websockets?'
def _routing_call(self, call, callargs, context=None): """ Endpoints call into here to synchronize across the entire IonProcess. Returns immediately with an AsyncResult that can be waited on. Calls are made by the loop in _control_flow. We pass in the calling greenlet so exceptions are raised in the correct context. @param call The call to be made within this ION processes' calling greenlet. @param callargs The keyword args to pass to the call. @param context Optional process-context (usually the headers of the incoming call) to be set. Process-context is greenlet-local, and since we're crossing greenlet boundaries, we must set it again in the ION process' calling greenlet. """ ar = AsyncResult() self._ctrl_queue.put((greenlet.getcurrent(), ar, call, callargs, context)) return ar
def _routing_call(self, call, callargs, context=None): """ Endpoints call into here to synchronize across the entire IonProcess. Returns immediately with an AsyncResult that can be waited on. Calls are made by the loop in _control_flow. We pass in the calling greenlet so exceptions are raised in the correct context. @param call The call to be made within this ION processes' calling greenlet. @param callargs The keyword args to pass to the call. @param context Optional process-context (usually the headers of the incoming call) to be set. Process-context is greenlet-local, and since we're crossing greenlet boundaries, we must set it again in the ION process' calling greenlet. """ ar = AsyncResult() self._ctrl_queue.put( (greenlet.getcurrent(), ar, call, callargs, context)) return ar
def stop(self, gevent_group, force=False): """ Stop the user greenlet that exists in the gevent_group. :param gevent_group: Group instance where the greenlet will be spawned. :type gevent_group: gevent.pool.Group :param force: If False (the default) the stopping is done gracefully by setting the state to LOCUST_STATE_STOPPING which will make the User instance stop once any currently running task is complete and on_stop methods are called. If force is True the greenlet will be killed immediately. :returns: True if the greenlet was killed immediately, otherwise False """ if self._greenlet is greenlet.getcurrent(): # the user is stopping itself (from within a task), so blocking would deadlock gevent_group.killone(self._greenlet, block=False) return True elif force or self._state == LOCUST_STATE_WAITING: gevent_group.killone(self._greenlet) return True elif self._state == LOCUST_STATE_RUNNING: self._state = LOCUST_STATE_STOPPING return False
print(a) gevent.sleep(1) print('switch back to task') gevent.sleep(1) print('switch back to task') gevent.sleep(1) print('task done') task = gevent.spawn(test, 'hello') print(task) print(task.parent) h = get_hub() print(h) print(h.parent) g = getcurrent() print(g) print(g.parent) gevent.sleep(1) # time.sleep(1) print('switch back to main') gevent.sleep(1) print('main done') gevent.joinall([task]) """ current greenlet == greenlet.greenlet => Hub => greenlet current greenlet 也可由Hub调度 gevent.sleep=>hub.wait """