Source code for artiq.protocols.fire_and_forget

import threading
import logging


logger = logging.getLogger(__name__)


[docs]class FFProxy: """Proxies a target object and runs its methods in the background. All method calls to this object are forwarded to the target and executed in a background thread. Method calls return immediately. Exceptions from the target method are turned into warnings. At most one method from the target object may be executed in the background; if a new call is submitted while the previous one is still executing, a warning is printed and the new call is dropped. This feature is typically used to wrap slow and non-critical RPCs in experiments. """ def __init__(self, target): self.target = target self._thread = None
[docs] def ff_join(self): """Waits until any background method finishes its execution.""" if self._thread is not None: self._thread.join()
def __getattr__(self, k): def run_in_thread(*args, **kwargs): if self._thread is not None and self._thread.is_alive(): logger.warning("skipping fire-and-forget call to %r.%s as " "previous call did not complete", self.target, k) return def thread_body(): try: getattr(self.target, k)(*args, **kwargs) except: logger.warning("fire-and-forget call to %r.%s raised an " "exception:", self.target, k, exc_info=True) self._thread = threading.Thread(target=thread_body) self._thread.start() return run_in_thread