class_docstr: _PreemptionWatcher connects to the master and asynchronously waits for a preemption signal.
  
  _PreemptionWatcher.should_preempt() is non-blocking (after the initial contact is made with the
  master) and returns a bool indicating if a preemption signal has been received yet.
  
  Example usage:
  
  .. code:: python
  
     with _PreemptionWatcher(session, allocation_id) as p:
         print("started!")
         for i in range(10):
             if p.should_preempt():
                 print("preempted!")
                 break
             print('no preemption yet, waiting...')
             time.sleep(1)
         else:
             print('finished without preemption signal')
class_docstr_tok: ["_PreemptionWatcher","connects","to","the","master","and","asynchronously","waits","for","a","preemption","signal",".","_PreemptionWatcher.should_preempt","(",")","is","non-blocking","(","after","the","initial","contact","is","made","with","the","master",")","and","returns","a","bool","indicating","if","a","preemption","signal","has","been","received","yet",".","Example","usage",":","..","code",":",":","python","with","_PreemptionWatcher","(","session",",","allocation_id",")","as","p",":","print","(","``","started","!","''",")","for","i","in","range","(","10",")",":","if","p.should_preempt","(",")",":","print","(","``","preempted","!","''",")","break","print","(","'no","preemption","yet",",","waiting","...","'",")","time.sleep","(","1",")","else",":","print","(","'finished","without","preemption","signal","'",")"]
code: def run(self) -> None:
      # Do a rapid check for the initial value.
      with self._cond:
          try:
              self._should_preempt = self._get_preemption(0)
          except requests.Timeout:
              logger.warning(
                  "timeout during initial preemption API check (continuing):",
                  exc_info=True,
              )
              self._should_preempt = False
          except Exception:
              logger.warning(
                  "failure during initial preemption API check (continuing):",
                  exc_info=True,
              )
              self._should_preempt = False
          finally:
              # Wake the main thread in case it was waiting for the initial response.
              self._cond.notify()
  
      # Continuously poll for preemption status to change.  Always retry after network failures;
      # if the master is unreachable, either user code will exit due to some more critical API
      # failure, or the user will kill the task.
      while not self._should_preempt and not self._should_quit:
          try:
              self._should_preempt = self._get_preemption(60)
          except requests.Timeout:
              logger.warning(
                  "timeout communicating with preemption API (retrying):",
                  exc_info=True,
              )
          except Exception:
              logger.warning(
                  "failure communicating with preemption API (retrying in 10s):",
                  exc_info=True,
              )
              time.sleep(10)
  
imports: import enum
  import logging
  import threading
  import time
  from typing import Any, Optional
  import requests
  from determined import core
  from determined.common import api
label_desc: Use image node_id 3 for calling the _PreemptionWatcher obj's underlying member method code with example usage: obj.run() without return types