Python gevent.event() Examples

The following are 30 code examples of gevent.event(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module gevent , or try the search function .
Example #1
Source File: agent.py    From eavatar-me with Apache License 2.0 6 votes vote down vote up
def send(self, signal=dispatcher.Any, sender=dispatcher.Anonymous,
             *args, **kwargs):
        """
        Send signal/event to registered receivers.

        :param args:
        :param kwargs:
        :return:
        """
        if signal is None:
            signal = dispatcher.Any
        if sender is None:
            sender = dispatcher.Anonymous

        self._dispatcher.send(signal, sender, *args, **kwargs)

        # dispatch this signal to the shell.

        logger.info("sending signal: %s", signal)

        if self._outbox:
            self._outbox.put_nowait((signal, kwargs)) 
Example #2
Source File: basepoller.py    From minemeld-core with Apache License 2.0 6 votes vote down vote up
def __init__(self, name, chassis, config):
        self.table = None
        self.agg_table = None

        self._actor_queue = gevent.queue.Queue(maxsize=128)
        self._actor_glet = None
        self._actor_commands_ts = collections.defaultdict(int)
        self._poll_glet = None
        self._age_out_glet = None
        self._emit_counter = 0

        self.last_run = None
        self.last_successful_run = None
        self.last_ageout_run = None
        self._sub_state = None
        self._sub_state_message = None

        self.poll_event = gevent.event.Event()

        self.state_lock = RWLock()

        super(BasePollerFT, self).__init__(name, chassis, config) 
Example #3
Source File: queryprocessor.py    From minemeld-core with Apache License 2.0 6 votes vote down vote up
def __init__(self, comm, store, config=None):
        if config is None:
            config = {}

        self._stop = gevent.event.Event()

        self.max_concurrency = config.get('max_concurrency', 10)
        self.redis_config = config.get('redis', {})
        self.store = store

        self.queries_lock = gevent.lock.BoundedSemaphore()
        self.queries = {}

        comm.request_rpc_server_channel(
            QUERY_QUEUE,
            self,
            allowed_methods=['query', 'kill_query']
        ) 
Example #4
Source File: writer.py    From minemeld-core with Apache License 2.0 6 votes vote down vote up
def __init__(self, comm, store, topic, config):
        self._stop = gevent.event.Event()
        self._low_disk = gevent.event.Event()

        self.store = store
        self.comm = comm
        self.comm.request_sub_channel(
            topic,
            self,
            allowed_methods=['log'],
            name='mbus:log:writer',
            multi_write=True
        )

        self._disk_monitor_glet = DiskSpaceMonitor(
            threshold=config.get('threshold', 70),
            low_disk=self._low_disk
        )
        self._disk_monitor_glet.start() 
Example #5
Source File: console_service.py    From pyethapp with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def enable(self, app=None):
        """Enable event loop integration with gevent.
        Parameters
        ----------
        app : ignored
            Ignored, it's only a placeholder to keep the call signature of all
            gui activation methods consistent, which simplifies the logic of
            supporting magics.
        Notes
        -----
        This methods sets the PyOS_InputHook for gevent, which allows
        gevent greenlets to run in the background while interactively using
        IPython.
        """
        self.manager.set_inputhook(inputhook_gevent)
        self._current_gui = GUI_GEVENT
        return app 
Example #6
Source File: backend_session.py    From janus-cloud with GNU Affero General Public License v3.0 6 votes vote down vote up
def _recv_msg_cbk(self, msg):
        try:
            if 'transaction' in msg:
                transaction = self._transactions.get(msg['transaction'], None)
                if transaction:
                    transaction.response = msg
            elif msg['janus'] == 'timeout':
                log.debug('Receive session timeout from Janus server: {}'.format(self.url))
                self.destroy()
            elif msg['janus'] == 'detached':
                log.debug('Receive async event {} from Janus server: {}'.format(msg, self.url))
                handle = self._handles.pop(msg['sender'], None)
                if handle:
                    handle.on_close()
            elif 'sender' in msg:
                log.debug('Receive async event {} from Janus server: {}'.format(msg, self.url))
                handle = self._handles.get(msg['sender'], None)
                if handle:
                    handle.on_async_event(msg)
            else:
                log.warn('Receive a invalid message {} on session {} for server {}'.format(msg, self.session_id, self.url))
        except Exception:
            log.exception('Received a malformat msg {}'.format(msg)) 
Example #7
Source File: api.py    From AIT-Core with MIT License 6 votes vote down vote up
def __init__(self, iterable=None, maxlen=None):
        """Returns a new GeventDeque object initialized left-to-right
        (using append()) with data from *iterable*. If *iterable* is
        not specified, the new GeventDeque is empty.

        If *maxlen* is not specified or is ``None``, GeventDeques may
        grow to an arbitrary length.  Otherwise, the GeventDeque is
        bounded to the specified maximum length.  Once a bounded
        length GeventDeque is full, when new items are added, a
        corresponding number of items are discarded from the opposite
        end.
        """
        if iterable is None:
            self._deque = collections.deque(maxlen=maxlen)
        else:
            self._deque = collections.deque(iterable, maxlen)

        self.notEmpty = gevent.event.Event()

        if len(self._deque) > 0:
            self.notEmpty.set() 
Example #8
Source File: actions.py    From sync-engine with GNU Affero General Public License v3.0 6 votes vote down vote up
def _mark_action_as_failed(self, action_log_entry, db_session):
        self.log.critical('Max retries reached, giving up.', exc_info=True)
        action_log_entry.status = 'failed'
        self._log_to_statsd(action_log_entry.status)

        if action_log_entry.action == 'create_event':
            # Creating a remote copy of the event failed.
            # Without it, none of the other pending actions
            # for this event will succeed. To prevent their
            # execution, preemptively mark them as failed.
            actions = db_session.query(ActionLog).filter_by(
                        record_id=action_log_entry.record_id,
                        namespace_id=action_log_entry.namespace_id,
                        status='pending').all()
            for pending_action in actions:
                pending_action.status = 'failed'

            # Mark the local copy as deleted so future actions can't be made.
            event = db_session.query(Event).get(action_log_entry.record_id)
            event.deleted_at = datetime.now()
        db_session.commit() 
Example #9
Source File: zookeeper.py    From scales with MIT License 5 votes vote down vote up
def __enter__(self):
      if self._count == 0:
        self.event.clear()
      self._count += 1 
Example #10
Source File: monitor_network.py    From powerpool with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def new_merged_work(self, event):
        self.generate_job(push=True, flush=event.flush, network='aux') 
Example #11
Source File: core.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __cleanup_events(self):
        # close the _state_event event, keeps the number of active file descriptors down
        if getattr(self, '_state_event', None):
            _stop(self._state_event)
            self._state_event = None
        # if the socket has entered a close state resume any waiting greenlets
        self.__writable.set()
        self.__readable.set() 
Example #12
Source File: zookeeper.py    From scales with MIT License 5 votes vote down vote up
def __exit__(self, exc_type, exc_val, exc_tb):
      self._count -= 1
      if self._count == 0:
        self.event.set() 
Example #13
Source File: core.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __state_changed(self, event=None, _evtype=None):
        if self.closed:
            self.__cleanup_events()
            return
        try:
            # avoid triggering __state_changed from inside __state_changed
            events = super(_Socket, self).getsockopt(zmq.EVENTS)
        except zmq.ZMQError as exc:
            self.__writable.set_exception(exc)
            self.__readable.set_exception(exc)
        else:
            if events & zmq.POLLOUT:
                self.__writable.set()
            if events & zmq.POLLIN:
                self.__readable.set() 
Example #14
Source File: core.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _wait_write(self):
        assert self.__writable.ready(), "Only one greenlet can be waiting on this event"
        self.__writable = AsyncResult()
        # timeout is because libzmq cannot be trusted to properly signal a new send event:
        # this is effectively a maximum poll interval of 1s
        tic = time.time()
        dt = self._gevent_bug_timeout
        if dt:
            timeout = gevent.Timeout(seconds=dt)
        else:
            timeout = None
        try:
            if timeout:
                timeout.start()
            self.__writable.get(block=True)
        except gevent.Timeout as t:
            if t is not timeout:
                raise
            toc = time.time()
            # gevent bug: get can raise timeout even on clean return
            # don't display zmq bug warning for gevent bug (this is getting ridiculous)
            if self._debug_gevent and timeout and toc-tic > dt and \
                    self.getsockopt(zmq.EVENTS) & zmq.POLLOUT:
                print("BUG: gevent may have missed a libzmq send event on %i!" % self.FD, file=sys.stderr)
        finally:
            if timeout:
                timeout.cancel()
            self.__writable.set() 
Example #15
Source File: core.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _wait_read(self):
        assert self.__readable.ready(), "Only one greenlet can be waiting on this event"
        self.__readable = AsyncResult()
        # timeout is because libzmq cannot always be trusted to play nice with libevent.
        # I can only confirm that this actually happens for send, but lets be symmetrical
        # with our dirty hacks.
        # this is effectively a maximum poll interval of 1s
        tic = time.time()
        dt = self._gevent_bug_timeout
        if dt:
            timeout = gevent.Timeout(seconds=dt)
        else:
            timeout = None
        try:
            if timeout:
                timeout.start()
            self.__readable.get(block=True)
        except gevent.Timeout as t:
            if t is not timeout:
                raise
            toc = time.time()
            # gevent bug: get can raise timeout even on clean return
            # don't display zmq bug warning for gevent bug (this is getting ridiculous)
            if self._debug_gevent and timeout and toc-tic > dt and \
                    self.getsockopt(zmq.EVENTS) & zmq.POLLIN:
                print("BUG: gevent may have missed a libzmq recv event on %i!" % self.FD, file=sys.stderr)
        finally:
            if timeout:
                timeout.cancel()
            self.__readable.set() 
Example #16
Source File: core.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def send(self, data, flags=0, copy=True, track=False, **kwargs):
        """send, which will only block current greenlet
        
        state_changed always fires exactly once (success or fail) at the
        end of this method.
        """
        
        # if we're given the NOBLOCK flag act as normal and let the EAGAIN get raised
        if flags & zmq.NOBLOCK:
            try:
                msg = super(_Socket, self).send(data, flags, copy, track, **kwargs)
            finally:
                if not self.__in_send_multipart:
                    self.__state_changed()
            return msg
        # ensure the zmq.NOBLOCK flag is part of flags
        flags |= zmq.NOBLOCK
        while True: # Attempt to complete this operation indefinitely, blocking the current greenlet
            try:
                # attempt the actual call
                msg = super(_Socket, self).send(data, flags, copy, track)
            except zmq.ZMQError as e:
                # if the raised ZMQError is not EAGAIN, reraise
                if e.errno != zmq.EAGAIN:
                    if not self.__in_send_multipart:
                        self.__state_changed()
                    raise
            else:
                if not self.__in_send_multipart:
                    self.__state_changed()
                return msg
            # defer to the event loop until we're notified the socket is writable
            self._wait_write() 
Example #17
Source File: actions.py    From sync-engine with GNU Affero General Public License v3.0 5 votes vote down vote up
def __init__(self, syncback_id, process_number, total_processes, poll_interval=1,
                 retry_interval=30, num_workers=NUM_PARALLEL_ACCOUNTS,
                 batch_size=10):
        self.process_number = process_number
        self.total_processes = total_processes
        self.poll_interval = poll_interval
        self.retry_interval = retry_interval
        self.batch_size = batch_size
        self.keep_running = True
        self.workers = gevent.pool.Group()
        # Dictionary account_id -> semaphore to serialize action syncback for
        # any particular account.
        # TODO(emfree): We really only need to serialize actions that operate
        # on any given object. But IMAP actions are already effectively
        # serialized by using an IMAP connection pool of size 1, so it doesn't
        # matter too much.
        self.account_semaphores = defaultdict(lambda: BoundedSemaphore(1))
        # This SyncbackService performs syncback for only and all the accounts
        # on shards it is reponsible for; shards are divided up between
        # running SyncbackServices.
        self.log = logger.new(component='syncback')
        syncback_assignments = config.get("SYNCBACK_ASSIGNMENTS", {})
        if syncback_id in syncback_assignments:
            self.keys = [key for key in engine_manager.engines
                         if key in syncback_assignments[syncback_id] and
                         key % total_processes == process_number]
        else:
            self.log.warn("No shards assigned to syncback server",
                          syncback_id=syncback_id)
            self.keys = []

        self.log = logger.new(component='syncback')
        self.num_workers = num_workers
        self.num_idle_workers = 0
        self.worker_did_finish = gevent.event.Event()
        self.worker_did_finish.clear()
        self.task_queue = Queue()
        self.running_action_ids = set()
        gevent.Greenlet.__init__(self) 
Example #18
Source File: gevent_uwsgi.py    From python-engineio with MIT License 5 votes vote down vote up
def __call__(self, environ, start_response):
        self._sock = uwsgi.connection_fd()
        self.environ = environ

        uwsgi.websocket_handshake()

        self._req_ctx = None
        if hasattr(uwsgi, 'request_context'):
            # uWSGI >= 2.1.x with support for api access across-greenlets
            self._req_ctx = uwsgi.request_context()
        else:
            # use event and queue for sending messages
            from gevent.event import Event
            from gevent.queue import Queue
            from gevent.select import select
            self._event = Event()
            self._send_queue = Queue()

            # spawn a select greenlet
            def select_greenlet_runner(fd, event):
                """Sets event when data becomes available to read on fd."""
                while True:
                    event.set()
                    try:
                        select([fd], [], [])[0]
                    except ValueError:
                        break
            self._select_greenlet = gevent.spawn(
                select_greenlet_runner,
                self._sock,
                self._event)

        self.app(self) 
Example #19
Source File: zookeeper.py    From scales with MIT License 5 votes vote down vote up
def __init__(self):
      self.event = Event()
      self.event.set()
      self._count = 0 
Example #20
Source File: serverset.py    From aurproxy with Apache License 2.0 5 votes vote down vote up
def ensure_safe(self):
      self.event.wait() 
Example #21
Source File: core.py    From pySINDy with MIT License 5 votes vote down vote up
def send(self, data, flags=0, copy=True, track=False, **kwargs):
        """send, which will only block current greenlet
        
        state_changed always fires exactly once (success or fail) at the
        end of this method.
        """
        
        # if we're given the NOBLOCK flag act as normal and let the EAGAIN get raised
        if flags & zmq.NOBLOCK:
            try:
                msg = super(_Socket, self).send(data, flags, copy, track, **kwargs)
            finally:
                if not self.__in_send_multipart:
                    self.__state_changed()
            return msg
        # ensure the zmq.NOBLOCK flag is part of flags
        flags |= zmq.NOBLOCK
        while True: # Attempt to complete this operation indefinitely, blocking the current greenlet
            try:
                # attempt the actual call
                msg = super(_Socket, self).send(data, flags, copy, track)
            except zmq.ZMQError as e:
                # if the raised ZMQError is not EAGAIN, reraise
                if e.errno != zmq.EAGAIN:
                    if not self.__in_send_multipart:
                        self.__state_changed()
                    raise
            else:
                if not self.__in_send_multipart:
                    self.__state_changed()
                return msg
            # defer to the event loop until we're notified the socket is writable
            self._wait_write() 
Example #22
Source File: core.py    From pySINDy with MIT License 5 votes vote down vote up
def _wait_read(self):
        assert self.__readable.ready(), "Only one greenlet can be waiting on this event"
        self.__readable = AsyncResult()
        # timeout is because libzmq cannot always be trusted to play nice with libevent.
        # I can only confirm that this actually happens for send, but lets be symmetrical
        # with our dirty hacks.
        # this is effectively a maximum poll interval of 1s
        tic = time.time()
        dt = self._gevent_bug_timeout
        if dt:
            timeout = gevent.Timeout(seconds=dt)
        else:
            timeout = None
        try:
            if timeout:
                timeout.start()
            self.__readable.get(block=True)
        except gevent.Timeout as t:
            if t is not timeout:
                raise
            toc = time.time()
            # gevent bug: get can raise timeout even on clean return
            # don't display zmq bug warning for gevent bug (this is getting ridiculous)
            if self._debug_gevent and timeout and toc-tic > dt and \
                    self.getsockopt(zmq.EVENTS) & zmq.POLLIN:
                print("BUG: gevent may have missed a libzmq recv event on %i!" % self.FD, file=sys.stderr)
        finally:
            if timeout:
                timeout.cancel()
            self.__readable.set() 
Example #23
Source File: core.py    From pySINDy with MIT License 5 votes vote down vote up
def _wait_write(self):
        assert self.__writable.ready(), "Only one greenlet can be waiting on this event"
        self.__writable = AsyncResult()
        # timeout is because libzmq cannot be trusted to properly signal a new send event:
        # this is effectively a maximum poll interval of 1s
        tic = time.time()
        dt = self._gevent_bug_timeout
        if dt:
            timeout = gevent.Timeout(seconds=dt)
        else:
            timeout = None
        try:
            if timeout:
                timeout.start()
            self.__writable.get(block=True)
        except gevent.Timeout as t:
            if t is not timeout:
                raise
            toc = time.time()
            # gevent bug: get can raise timeout even on clean return
            # don't display zmq bug warning for gevent bug (this is getting ridiculous)
            if self._debug_gevent and timeout and toc-tic > dt and \
                    self.getsockopt(zmq.EVENTS) & zmq.POLLOUT:
                print("BUG: gevent may have missed a libzmq send event on %i!" % self.FD, file=sys.stderr)
        finally:
            if timeout:
                timeout.cancel()
            self.__writable.set() 
Example #24
Source File: core.py    From pySINDy with MIT License 5 votes vote down vote up
def __state_changed(self, event=None, _evtype=None):
        if self.closed:
            self.__cleanup_events()
            return
        try:
            # avoid triggering __state_changed from inside __state_changed
            events = super(_Socket, self).getsockopt(zmq.EVENTS)
        except zmq.ZMQError as exc:
            self.__writable.set_exception(exc)
            self.__readable.set_exception(exc)
        else:
            if events & zmq.POLLOUT:
                self.__writable.set()
            if events & zmq.POLLIN:
                self.__readable.set() 
Example #25
Source File: core.py    From pySINDy with MIT License 5 votes vote down vote up
def __cleanup_events(self):
        # close the _state_event event, keeps the number of active file descriptors down
        if getattr(self, '_state_event', None):
            _stop(self._state_event)
            self._state_event = None
        # if the socket has entered a close state resume any waiting greenlets
        self.__writable.set()
        self.__readable.set() 
Example #26
Source File: session_store.py    From qdb with Apache License 2.0 5 votes vote down vote up
def slaughter(self, uuid, mode='soft'):
        """
        Slaughters a session, closing all clients and the tracer.
        This also removes the session from the list of sessions.
        If mode is 'soft', the tracer clears all breakpoints and continues
        execution. If it is 'hard', it raises a QdbQuit in the tracer process.
        """
        session = self._sessions.get(uuid)
        if not session:
            return  # Slaughtering a session that does not exits.
        # Close all the clients.
        disable_event = fmt_msg('disable')
        self.send_to_clients(uuid, event=disable_event)
        for client in session.clients:
            try:
                client.close()
            except WebSocketError as e:
                if str(e) != 'Socket is dead' or e.errno not in safe_errnos:
                    log.exception(
                        'Exception caught while killing client for '
                        'session %s:' % uuid
                    )
        # Close the tracer if we had one.
        if session.tracer:
            try:
                disable_event['p'] = mode
                self.send_to_tracer(uuid, event=disable_event)
                session.tracer.close()
            except socket.error as e:
                if e.errno not in safe_errnos:
                    log.exception(
                        'Exception caught while killing tracer for session %s:'
                        % uuid
                    )
        del self._sessions[uuid]
        log.info('Debugging session %s has been terminated' % uuid) 
Example #27
Source File: session_store.py    From qdb with Apache License 2.0 5 votes vote down vote up
def send_to_clients(self, uuid, event):
        """
        Routes an event to all clients connected to a session.
        """
        if uuid not in self._sessions:
            log.warn('send_to_clients failed: session %s does not exist'
                     % uuid)
            return  # Session doesn't exist.

        try:
            msg = fmt_msg(event['e'], event.get('p'), serial=json.dumps)
        except (KeyError, ValueError) as e:
            log.warn('send_to_clients(uuid=%s, event=%s) failed: %s'
                     % (uuid, event, e))
            raise

        clients = self._sessions[uuid].clients

        with self._lock:
            for client in set(clients):
                try:
                    client.send(msg)
                except Exception:
                    log.info('Client was closed for debug session: %s' % uuid)
                    clients.remove(client)

        self._update_timestamp(uuid) 
Example #28
Source File: session_store.py    From qdb with Apache License 2.0 5 votes vote down vote up
def send_to_tracer(self, uuid, event):
        """
        Sends an event the tracer uuid.
        """
        if uuid not in self._sessions:
            log.warn('send_to_tracer failed: session %s does not exist'
                     % uuid)
            return  # Session doesn't exist.

        try:
            if event['e'] == 'pause' and self.is_local(uuid):
                self.pause_tracer(uuid)
                log.info('Raising pause signal (%d) in server local session %s'
                         % (self._sessions[uuid].pause_signal, uuid))
                self._update_timestamp(uuid)
                return  # We 'sent' this event.
            msg = fmt_msg(event['e'], event.get('p'), serial=json.dumps)
        except (ValueError, KeyError) as e:
            log.warn('send_to_tracer(uuid=%s, event=%s) failed: %s'
                     % (uuid, event, e))
            raise  # The event is just wrong, reraise this to the user.

        sck = self._sessions[uuid].tracer
        if sck:
            self._send_to_socket(sck, msg)
        else:
            log.warn('No client session is alive for %s' % uuid)
        self._update_timestamp(uuid) 
Example #29
Source File: session_store.py    From qdb with Apache License 2.0 5 votes vote down vote up
def __init__(self,
                 inactivity_timeout=10,  # minutes
                 sweep_time=1,  # minute
                 attach_timeout=60,  # seconds
                 timeout_disable_mode='soft'):
        """
        inactivity_timeout is the amount of time in minutes that a session may
        go without any messages being sent before it is killed. If
        inactivity_timeout is None, then sessions may sit innactive forever.
        sweep_time is the amount of time in minutes between checks to kill
        inactive sessions.
        attach_timeout is the amount of time in secondsto wait for both sides
        of a session to attach before killing one off. If attach_timeout is
        None, then it will wait forever. If attach_timeout is 0, then it will
        allow for orphaned sessions, meaning a clients with no tracer, or a
        tracer with no clients. These may be attached later.
        timeout_disable_mode is the mode to kill the sessions with in the event
        of a timeout. This mode may be 'hard' or 'soft'.
        """
        if timeout_disable_mode not in ['soft', 'hard']:
            raise ValueError("timeout_disable_mode must be 'hard' or 'soft'")
        self.inactivity_timeout = inactivity_timeout
        self.sweep_time = sweep_time
        self.attach_timeout = attach_timeout
        self.timeout_disable_mode = timeout_disable_mode
        self._sessions = {}
        self.gc_glet = None
        self._lock = RLock() 
Example #30
Source File: core.py    From Computable with MIT License 5 votes vote down vote up
def send(self, data, flags=0, copy=True, track=False):
        """send, which will only block current greenlet
        
        state_changed always fires exactly once (success or fail) at the
        end of this method.
        """
        
        # if we're given the NOBLOCK flag act as normal and let the EAGAIN get raised
        if flags & zmq.NOBLOCK:
            try:
                msg = super(_Socket, self).send(data, flags, copy, track)
            finally:
                if not self.__in_send_multipart:
                    self.__state_changed()
            return msg
        # ensure the zmq.NOBLOCK flag is part of flags
        flags |= zmq.NOBLOCK
        while True: # Attempt to complete this operation indefinitely, blocking the current greenlet
            try:
                # attempt the actual call
                msg = super(_Socket, self).send(data, flags, copy, track)
            except zmq.ZMQError as e:
                # if the raised ZMQError is not EAGAIN, reraise
                if e.errno != zmq.EAGAIN:
                    if not self.__in_send_multipart:
                        self.__state_changed()
                    raise
            else:
                if not self.__in_send_multipart:
                    self.__state_changed()
                return msg
            # defer to the event loop until we're notified the socket is writable
            self._wait_write()