class_docstr: A utility class to register callbacks when a zmq socket sends and receives
  
  For use with tornado IOLoop.
  
  There are three main methods
  
  Methods:
  
  * **on_recv(callback, copy=True):**
      register a callback to be run every time the socket has something to receive
  * **on_send(callback):**
      register a callback to be run every time you call send
  * **send_multipart(self, msg, flags=0, copy=False, callback=None):**
      perform a send that will trigger the callback
      if callback is passed, on_send is also called.
  
      There are also send_multipart(), send_json(), send_pyobj()
  
  Three other methods for deactivating the callbacks:
  
  * **stop_on_recv():**
      turn off the recv callback
  * **stop_on_send():**
      turn off the send callback
  
  which simply call ``on_<evt>(None)``.
  
  The entire socket interface, excluding direct recv methods, is also
  provided, primarily through direct-linking the methods.
  e.g.
  
  >>> stream.bind is stream.socket.bind
  True
  
  
  .. versionadded:: 25
  
      send/recv callbacks can be coroutines.
  
  .. versionchanged:: 25
  
      ZMQStreams only support base zmq.Socket classes (this has always been true, but not enforced).
      If ZMQStreams are created with e.g. async Socket subclasses,
      a RuntimeWarning will be shown,
      and the socket cast back to the default zmq.Socket
      before connecting events.
  
      Previously, using async sockets (or any zmq.Socket subclass) would result in undefined behavior for the
      arguments passed to callback functions.
      Now, the callback functions reliably get the return value of the base `zmq.Socket` send/recv_multipart methods
      (the list of message frames).
docstr: Flush pending messages.
  
  This method safely handles all pending incoming and/or outgoing messages,
  bypassing the inner loop, passing them to the registered callbacks.
  
  A limit can be specified, to prevent blocking under high load.
  
  flush will return the first time ANY of these conditions are met:
      * No more events matching the flag are pending.
      * the total number of events handled reaches the limit.
  
  Note that if ``flag|POLLIN != 0``, recv events will be flushed even if no callback
  is registered, unlike normal IOLoop operation. This allows flush to be
  used to remove *and ignore* incoming messages.
  
  Parameters
  ----------
  flag : int, default=POLLIN|POLLOUT
          0MQ poll flags.
          If flag|POLLIN,  recv events will be flushed.
          If flag|POLLOUT, send events will be flushed.
          Both flags can be set at once, which is the default.
  limit : None or int, optional
          The maximum number of messages to send or receive.
          Both send and recv count against this limit.
  
  Returns
  -------
  int : count of events handled (both send and recv)
docstr_tok: ["Flush","pending","messages",".","This","method","safely","handles","all","pending","incoming","and\/or","outgoing","messages",",","bypassing","the","inner","loop",",","passing","them","to","the","registered","callbacks",".","A","limit","can","be","specified",",","to","prevent","blocking","under","high","load",".","flush","will","return","the","first","time","ANY","of","these","conditions","are","met",":","*","No","more","events","matching","the","flag","are","pending",".","*","the","total","number","of","events","handled","reaches","the","limit",".","Note","that","if","``","flag|POLLIN","!","=","0","``",",","recv","events","will","be","flushed","even","if","no","callback","is","registered",",","unlike","normal","IOLoop","operation",".","This","allows","flush","to","be","used","to","remove","*","and","ignore","*","incoming","messages",".","Parameters","--","--","--","--","--","flag",":","int",",","default=POLLIN|POLLOUT","0MQ","poll","flags",".","If","flag|POLLIN",",","recv","events","will","be","flushed",".","If","flag|POLLOUT",",","send","events","will","be","flushed",".","Both","flags","can","be","set","at","once",",","which","is","the","default",".","limit",":","None","or","int",",","optional","The","maximum","number","of","messages","to","send","or","receive",".","Both","send","and","recv","count","against","this","limit",".","Returns","--","--","--","-","int",":","count","of","events","handled","(","both","send","and","recv",")"]
code: def flush(
      self,
      flag: int = zmq.POLLIN | zmq.POLLOUT,
      limit: Optional[int] = None,
  ):
      """Flush pending messages.
  
      This method safely handles all pending incoming and/or outgoing messages,
      bypassing the inner loop, passing them to the registered callbacks.
  
      A limit can be specified, to prevent blocking under high load.
  
      flush will return the first time ANY of these conditions are met:
          * No more events matching the flag are pending.
          * the total number of events handled reaches the limit.
  
      Note that if ``flag|POLLIN != 0``, recv events will be flushed even if no callback
      is registered, unlike normal IOLoop operation. This allows flush to be
      used to remove *and ignore* incoming messages.
  
      Parameters
      ----------
      flag : int, default=POLLIN|POLLOUT
              0MQ poll flags.
              If flag|POLLIN,  recv events will be flushed.
              If flag|POLLOUT, send events will be flushed.
              Both flags can be set at once, which is the default.
      limit : None or int, optional
              The maximum number of messages to send or receive.
              Both send and recv count against this limit.
  
      Returns
      -------
      int : count of events handled (both send and recv)
      """
      self._check_closed()
      # unset self._flushed, so callbacks will execute, in case flush has
      # already been called this iteration
      already_flushed = self._flushed
      self._flushed = False
      # initialize counters
      count = 0
  
      def update_flag():
          """Update the poll flag, to prevent registering POLLOUT events
          if we don't have pending sends."""
          return flag & zmq.POLLIN | (
              self.sending() and flag & zmq.POLLOUT
          )
  
      flag = update_flag()
      if not flag:
          # nothing to do
          return 0
      self.poller.register(self.socket, flag)
      events = self.poller.poll(0)
      while events and (not limit or count < limit):
          s, event = events[0]
          if event & POLLIN:  # receiving
              self._handle_recv()
              count += 1
              if self.socket is None:
                  # break if socket was closed during callback
                  break
          if event & POLLOUT and self.sending():
              self._handle_send()
              count += 1
              if self.socket is None:
                  # break if socket was closed during callback
                  break
  
          flag = update_flag()
          if flag:
              self.poller.register(self.socket, flag)
              events = self.poller.poll(0)
          else:
              events = []
      if count:  # only bypass loop if we actually flushed something
          # skip send/recv callbacks this iteration
          self._flushed = True
          # reregister them at the end of the loop
          if not already_flushed:  # don't need to do it again
              self.io_loop.add_callback(self._finish_flush)
      elif already_flushed:
          self._flushed = True
  
      # update ioloop poll state, which may have changed
      self._rebuild_io_state()
      return count
  
imports: import asyncio
  import pickle
  import warnings
  from queue import Queue
  from typing import Any, Awaitable, Callable, List, Optional, Sequence, Union, cast, overload
  from tornado.ioloop import IOLoop
  from tornado.log import gen_log
  import zmq
  import zmq._future
  from zmq import POLLIN, POLLOUT
  from zmq._typing import Literal
  from zmq.utils import jsonapi
label_desc: Use image node_id 24 for calling the ZMQStream obj's underlying member method code with example usage: obj.flush(flag, limit) and returns: count, unknown, int