Beispiel #1
0
    def __internal_send(self, request: Event) -> ResultStatus:
        with self.lock:
            # Browse all queues
            to_delete = []
            for index in self.__queues.keys():
                # Reckon interrupted time
                interrupted_time = (
                    (time.time() - self.__interrupt_times[index]) if index in self.__interrupt_times and self.__interrupt_times[index] is not None else None
                )
                retain_timeout = RpcStaticConfig.EVENT_RETAIN_TIMEOUT.int_val

                # Interrupted queue + retain timeout expired?
                if interrupted_time is not None and interrupted_time >= retain_timeout:
                    # Yes, forget event queue
                    self.logger.info(f"Deleting interrupted event queue #{index} (retain timeout: {interrupted_time} >= {retain_timeout})")
                    to_delete.append(index)
                else:
                    # Still active queue: push event
                    self.__queues[index].put_nowait(request)

            # Forget timed out events (if any)
            if len(to_delete):
                for index in to_delete:
                    del self.__queues[index]
                    del self.__interrupt_times[index]
                self._persist_queues()

        return ResultStatus()
Beispiel #2
0
 def s_method2(self, request: SampleRequest) -> ResultStatus:
     for foo in ["abc", "def", "ghi", request.foo]:
         # Raise exception on "error" string
         if foo == "error":
             raise RpcException("Sample error occurred",
                                rc=ResultCode.ERROR_PARAM_INVALID)
         yield ResultStatus(r=Result(msg=foo))
Beispiel #3
0
    def proxy_register(self, request: ProxyRegisterRequest) -> ResultStatus:
        # Verify input params
        services = self.__check_proxy_names(request)
        if len(request.version) == 0 or request.port == 0:
            raise RpcException(
                "Missing input parameter in request (one of version or port)",
                ResultCode.ERROR_PARAM_MISSING)

        # Ready to update service proxy info
        with self.lock:
            for srv in services:
                # Update info
                srv.version = request.version
                srv.proxy_port = request.port
                srv.proxy_host = request.host

            # Persist proxy info
            self.__persist_proxies()

        # Send proxy registration event
        if self.__can_send_events:  # pragma: no branch
            self.client.events.send(
                RpcEvent(
                    name="RPC_PROXY_REGISTER",
                    properties=[
                        EventProperty(name="names",
                                      value=",".join(request.names)),
                        EventProperty(name="version", value=request.version),
                        EventProperty(name="port", value=str(request.port)),
                        EventProperty(name="host", value=request.host),
                    ],
                ))

        return ResultStatus()
Beispiel #4
0
    def interrupt(self, request: EventInterrupt) -> ResultStatus:
        # Known index?
        q = self.__get_queue(request.client_id)

        # Refuse to interrupt again already interrupted queue
        with self.lock:
            if request.client_id in self.__interrupt_times and self.__interrupt_times[request.client_id] is not None:
                raise RpcException(f"Already interrupted ID: {request.client_id}", ResultCode.ERROR_STATE_UNEXPECTED)

        # Put "None" event (will wait until listen loop is over)
        q.put(None)
        return ResultStatus()
Beispiel #5
0
    def report_exception(self, context, e: Exception):
        # Something happened during the RPC execution
        stack = "".join(traceback.format_tb(e.__traceback__))
        self.logger.error(f"Exception occurred: {e}\n{stack}")

        # Extract RC if this was a known error
        rc = e.rc if isinstance(e, RpcException) else ResultCode.ERROR

        # Build result according to return type
        r = Result(code=rc, msg=str(e), stack=stack)
        return ResultStatus(
            r=r) if self.return_type is None else self.return_type(r=r)
Beispiel #6
0
    def method1(self, request: Empty) -> ResultStatus:
        self.logger.info("In SampleServicer.method1!!!")

        # Sleep if requested
        if self.wait_a_bit:
            time.sleep(3)

        # Use auto-client to access other services (only if not shutdown in the meantime)
        s = None
        if not self.is_shutdown:
            s = self.client.srv.info(Filter())

        return ResultStatus(r=Result(
            msg=f"Found info count: {len(s.items) if s is not None else None}")
                            )
Beispiel #7
0
    def shutdown(self, request: ShutdownRequest = None) -> ResultStatus:
        """
        Shuts down this RPC server instance
        """

        # Only if not shutdown yet
        if self.__server is not None:
            # Make sure we won't enter here twice
            terminating_server = self.__server
            self.__server = None

            # Stop server and wait for termination
            self.logger.debug(
                f"Shutting down RPC server on port {self.__port}; stop accepting new requests"
            )
            terminating_server.stop(RpcStaticConfig.SHUTDOWN_GRACE.float_val)

            # Shutdown all managers
            self.logger.debug("Shutting down all managers")
            for descriptor in self.__real_descriptors:
                descriptor.manager._shutdown()

            # Is this an RPC call?
            if request is not None:
                # Yes --> delegate termination to its own thread, to return immediately from this request
                Thread(target=self.__finalize_shutdown,
                       kwargs={
                           "terminating_server": terminating_server,
                           "request": request
                       },
                       name="ShutdownThread").start()
            else:
                # Finalize shutdown immediately (internal call)
                self.__finalize_shutdown(terminating_server, None)

        # Always OK
        return ResultStatus()
Beispiel #8
0
    def proxy_forget(self, request: Filter) -> ResultStatus:
        # Verify input params
        services = self.__check_proxy_names(request)

        # Ready to update service proxy info
        with self.lock:
            for srv in services:
                # Update info
                srv.proxy_port = 0
                srv.proxy_host = ""

            # Persist proxy info
            self.__persist_proxies()

        # Send proxy forget event
        if self.__can_send_events:  # pragma: no branch
            self.client.events.send(
                RpcEvent(name="RPC_PROXY_FORGET",
                         properties=[
                             EventProperty(name="names",
                                           value=",".join(request.names))
                         ]))

        return ResultStatus()
Beispiel #9
0
 def s_method1(self, request: Iterable[SampleRequest]) -> ResultStatus:
     out = ""
     for req in request:
         self.logger.info(f"request: {req.foo}")
         out += req.foo
     return ResultStatus(r=Result(msg=out))