簡體   English   中英

可取消的后端調用的體系結構建議[如果可能,請添加zerorpc?

[英]Architecture recommendation for cancellable backend calls [zerorpc if possible?]

我有一個電子應用程序前端(zerorpc節點)與需要進行以下操作的python后端(zerorpc-python)進行通信:

a)能夠發送請求到后端[標准zerorpc調用]

b)能夠同時運行多個后端進程[遵循https://github.com/0rpc/zerorpc-node/issues/96中的體系結構)

c)能夠隨意取消后端進程[不確定如何使用當前架構執行此操作]

關於如何構建(c)解決方案的任何指導都將是很棒的。 如果有必要的話,如果有限制,我願意放棄zerorpc,但是如果解決方案涉及使用zerorpc,那就太好了。

我最終使用gipc來加速進程。 取消機制依賴於以下事實:當gipc進程終止時,管道關閉。 整個API很復雜,這就是我最終得到的結果:

class ZerorpcService():
    def __init__(self):
        self.participant_id = None
        self.extraction_methods = []
        # maps pid to (process, pipe writer)
        self.processes = {}
        self. = lock.Semaphore()

    def _launch_process(self, function, kwargs):
        """
        Launches a new process
        """
        try:
            # add required arguments
            pid = kwargs["pid"]

            # start independent gipc process, communicated via pipe
            started = False
            with gipc.pipe() as (r, w):
                with self.mutex:
                    if pid in self.processes:
                        return_value = {'status': 1, 'error': 'pid already exists', "report": True}
                        return
                    proc = gipc.start_process(self._process_wrapper, args=(function, kwargs, w))
                    self.processes[pid] = proc
                    started = True
                # wait for process to send something over pipe
                return_value = r.get()
        except EOFError as eof:
            # happens when we terminate a process because the pipe closes
            return_value = {'status': 1, 'error': "pid {} terminated".format(pid), "report": False}
        except Exception as error:
            logging.exception(error)
            return_value = {'status': 1, 'error': str(error), 'traceback': traceback.format_exc(), "report": True}
        finally:
            # deletes the pid from the map
            with self.mutex:
                if started:
                    del self.processes[pid]
            return return_value

    @staticmethod
    def _process_wrapper(function, kwargs, pipe):
        """
        Executes f with kwargs and formats the result into a dict.
        Wraps it in error handling.
        Routes the return value through the pipe provided.
        """
        return_val = {'status': 0}
        try:
            raw_val = function(**kwargs)
            if raw_val is not None:
                return_val = raw_val
        except Exception as error:
            logging.exception(error)
            return_val = {'status': 1, 'error': str(error), 'traceback': traceback.format_exc(), "report": True}
        finally:
            pipe.put(return_val)

    def cancel_process(self, pid):
        if pid in self.processes:
            with self.mutex:
                process = self.processes[pid]
                if process.is_alive():
                    process.terminate()
                return {'status': 0}
        else:
            return {'status': 1, 'error': 'pid {} not found'.format(pid), "traceback": traceback.format_exc(),
                    "report": True}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM