-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1 parent
a5b34be
commit 76e034c
Showing
2 changed files
with
58 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import threading | ||
import logging | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
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 | ||
|
||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters