class_docstr: This object serves as the interface between a ZMQ socket passing
  Requests and Replies, and a thread or threads serving those requests.
  Received requests are received on a ZMQ socket and placed on upward_queue,
  and notify_all() is called on updward_cv.  Replies (via the Request.reply()
  method) are dispatched to their requesters via a downward queue.
  
  The Boundary wakes up the socket thread via the notify socket. This lets
  the socket thread poll for changes on the notify and request sockets, but
  allows it to receive Python objects via the downward queue.
class_docstr_tok: ["This","object","serves","as","the","interface","between","a","ZMQ","socket","passing","Requests","and","Replies",",","and","a","thread","or","threads","serving","those","requests",".","Received","requests","are","received","on","a","ZMQ","socket","and","placed","on","upward_queue",",","and","notify_all","(",")","is","called","on","updward_cv",".","Replies","(","via","the","Request.reply","(",")","method",")","are","dispatched","to","their","requesters","via","a","downward","queue",".","The","Boundary","wakes","up","the","socket","thread","via","the","notify","socket",".","This","lets","the","socket","thread","poll","for","changes","on","the","notify","and","request","sockets",",","but","allows","it","to","receive","Python","objects","via","the","downward","queue","."]
docstr: Cancel an analysis
  
  All requests with the given analysis ID will get a BoundaryExited
  reply after this call returns.
docstr_tok: ["Cancel","an","analysis","All","requests","with","the","given","analysis","ID","will","get","a","BoundaryExited","reply","after","this","call","returns","."]
code: def cancel(self, analysis_id):
      """Cancel an analysis
  
      All requests with the given analysis ID will get a BoundaryExited
      reply after this call returns.
      """
      with self.analysis_context_lock:
          if self.analysis_context.cancelled:
              return
          self.analysis_context.cancel()
      response_queue = queue.Queue()
      self.send_to_boundary_thread(
          self.NOTIFY_CANCEL_ANALYSIS, (analysis_id, response_queue)
      )
      response_queue.get()
  
imports: import logging
  import queue
  import threading
  import zmq
  import cellprofiler_core.utilities.zmq
  from cellprofiler_core.utilities.zmq._analysis_context import AnalysisContext
  from .communicable import Communicable
  from .communicable.reply.upstream_exit import BoundaryExited
  from .communicable.request import AnalysisRequest, Request
  from ...constants.worker import NOTIFY_STOP, NOTIFY_RUN
label_desc: Use image node_id 5 for calling the Boundary obj's underlying member method code with example usage: obj.cancel(analysis_id) without return types