From afe983d6c907097c7fafab2ae8dac4bf8da5f775 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Sun, 29 Apr 2018 19:14:40 +0100 Subject: [PATCH] issue #212: service: support no_reply decorator. --- mitogen/service.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/mitogen/service.py b/mitogen/service.py index efab09cd..69774299 100644 --- a/mitogen/service.py +++ b/mitogen/service.py @@ -120,6 +120,18 @@ def expose(policy): return wrapper +def no_reply(): + """ + Annotate a method as one that does not generate a response. Messages sent + by the method are done so explicitly. This can be used for fire-and-forget + endpoints where the requestee never receives a reply. + """ + def wrapper(func): + func.mitogen_service__no_reply = True + return func + return wrapper + + class Service(object): #: Sentinel object to suppress reply generation, since returning ``None`` #: will trigger a response message containing the pickled ``None``. @@ -179,7 +191,20 @@ class Service(object): method = getattr(self, method_name) if 'msg' in method.func_code.co_varnames: kwargs['msg'] = msg # TODO: hack - return method(**kwargs) + + no_reply = getattr(method, 'mitogen_service__no_reply', False) + ret = None + try: + ret = method(**kwargs) + if no_reply: + return self.NO_REPLY + return ret + except Exception: + if no_reply: + LOG.exception('While calling no-reply method %s.%s', + type(self).__name__, method.func_name) + else: + raise def on_receive_message(self, msg): try: