class_docstr: Green version of :class:`zmq.Socket`
  
  The following methods are overridden:
  
      * send
      * recv
  
  To ensure that the ``zmq.NOBLOCK`` flag is set and that sending or receiving
  is deferred to the hub if a ``zmq.EAGAIN`` (retry) error is raised.
  
  The `__state_changed` method is triggered when the zmq.FD for the socket is
  marked as readable and triggers the necessary read and write events (which
  are waited for in the recv and send methods).
  
  Some double underscore prefixes are used to minimize pollution of
  :class:`zmq.Socket`'s namespace.
docstr: send, which will only block current greenlet
  
  state_changed always fires exactly once (success or fail) at the
  end of this method.
docstr_tok: ["send",",","which","will","only","block","current","greenlet","state_changed","always","fires","exactly","once","(","success","or","fail",")","at","the","end","of","this","method","."]
code: 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().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().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()
  
imports: import sys
  import time
  import warnings
  from typing import Tuple
  import gevent
  from gevent.event import AsyncResult
  from gevent.hub import get_hub
  import zmq
  from zmq import Context
  from zmq import Socket
  from .poll import _Poller
label_desc: Use image node_id 9 for calling the _Socket obj's underlying member method code with example usage: obj.send(data, flags, copy, track) and returns: msg, msg