def __call__( self, args: 'argparse.Namespace', is_started: Union['multiprocessing.Event', 'threading.Event'], is_shutdown: Union['multiprocessing.Event', 'threading.Event'], is_ready: Union['multiprocessing.Event', 'threading.Event'], is_cancelled: Union['multiprocessing.Event', 'threading.Event'], envs: Optional[Dict] = None, ): """Method responsible to manage a remote Pod This method is the target for the Pod's `thread` or `process` .. note:: Please note that env variables are process-specific. Subprocess inherits envs from the main process. But Subprocess's envs do NOT affect the main process. It does NOT mess up user local system envs. :param args: namespace args from the Pod :param is_started: concurrency event to communicate runtime is properly started. Used for better logging :param is_shutdown: concurrency event to communicate runtime is terminated :param is_ready: concurrency event to communicate runtime is ready to receive messages :param is_cancelled: concurrency event to receive cancelling signal from the Pod. Needed by some runtimes :param envs: a dictionary of environment variables to be passed to remote Pod """ self.args = args self.envs = envs self.is_started = is_started self.is_shutdown = is_shutdown self.is_ready = is_ready self.is_cancelled = is_cancelled self.pod_id = None self._logger = JinaLogger('RemotePod', **vars(args)) run_async(self._run)
def test_run_async(): async def dummy(): pass p = psutil.Process() run_async(dummy) first_fd_count = p.num_fds() for i in range(10): run_async(dummy) end_fd_count = p.num_fds() assert first_fd_count == end_fd_count
def dry_run(self, **kwargs) -> bool: """Sends a dry run to the Flow to validate if the Flow is ready to receive requests :param kwargs: potential kwargs received passed from the public interface :return: boolean indicating the health/readiness of the Flow """ return run_async(self.client._dry_run, **kwargs)
def func(self, func_name, *args, **kwargs): """convert async method `func_name` to a normal method :param func_name: name of method in super :param args: positional args :param kwargs: keyword args :return: run func_name from super """ f = getattr(super(), func_name, None) if f: return run_async(f, any_event_loop=True, *args, **kwargs)
def post( self, on: str, inputs: Optional['InputType'] = None, on_done: Optional['CallbackFnType'] = None, on_error: Optional['CallbackFnType'] = None, on_always: Optional['CallbackFnType'] = None, parameters: Optional[Dict] = None, target_executor: Optional[str] = None, request_size: int = 100, show_progress: bool = False, continue_on_error: bool = False, return_responses: bool = False, **kwargs, ) -> Optional[Union['DocumentArray', List['Response']]]: """Post a general data request to the Flow. :param inputs: input data which can be an Iterable, a function which returns an Iterable, or a single Document. :param on: the endpoint which is invoked. All the functions in the executors decorated by `@requests(on=...)` with the same endpoint are invoked. :param on_done: the function to be called when the :class:`Request` object is resolved. :param on_error: the function to be called when the :class:`Request` object is rejected. :param on_always: the function to be called when the :class:`Request` object is either resolved or rejected. :param parameters: the kwargs that will be sent to the executor :param target_executor: a regex string. Only matching Executors will process the request. :param request_size: the number of Documents per request. <=0 means all inputs in one request. :param show_progress: if set, client will show a progress bar on receiving every request. :param continue_on_error: if set, a Request that causes callback error will be logged only without blocking the further requests.7 :param return_responses: if set to True, the result will come as Response and not as a `DocumentArray` :param kwargs: additional parameters :return: None or DocumentArray containing all response Documents .. warning:: ``target_executor`` uses ``re.match`` for checking if the pattern is matched. ``target_executor=='foo'`` will match both deployments with the name ``foo`` and ``foo_what_ever_suffix``. """ c = self.client if c.args.return_responses and not return_responses: warnings.warn( 'return_responses was set in the Client constructor. Therefore, we are overriding the `.post()` input ' 'parameter `return_responses`. This argument will be deprecated from the `constructor` ' 'soon. We recommend passing `return_responses` to the `post` method.' ) return_responses = True c.show_progress = show_progress c.continue_on_error = continue_on_error parameters = _include_results_field_in_param(parameters) on_error = _wrap_on_error( on_error) if on_error is not None else on_error from jina import DocumentArray return_results = (on_always is None) and (on_done is None) async def _get_results(*args, **kwargs): result = [] if return_responses else DocumentArray() async for resp in c._get_results(*args, **kwargs): if return_results: if return_responses: result.append(resp) else: result.extend(resp.data.docs) if return_results: return result return run_async( _get_results, inputs=inputs, on_done=on_done, on_error=on_error, on_always=on_always, exec_endpoint=on, target_executor=target_executor, parameters=parameters, request_size=request_size, **kwargs, )
def post( self, on: str, inputs: Optional['InputType'] = None, on_done: Optional['CallbackFnType'] = None, on_error: Optional['CallbackFnType'] = None, on_always: Optional['CallbackFnType'] = None, parameters: Optional[Dict] = None, target_executor: Optional[str] = None, request_size: int = 100, show_progress: bool = False, continue_on_error: bool = False, return_results: bool = False, **kwargs, ) -> Optional[Union['DocumentArray', List['Response']]]: """Post a general data request to the Flow. :param inputs: input data which can be an Iterable, a function which returns an Iterable, or a single Document id. :param on: the endpoint is used for identifying the user-defined ``request_type``, labeled by ``@requests(on='/abc')`` :param on_done: the function to be called when the :class:`Request` object is resolved. :param on_error: the function to be called when the :class:`Request` object is rejected. :param on_always: the function to be called when the :class:`Request` object is either resolved or rejected. :param parameters: the kwargs that will be sent to the executor :param target_executor: a regex string. Only matching Executors will process the request. :param request_size: the number of Documents per request. <=0 means all inputs in one request. :param show_progress: if set, client will show a progress bar on receiving every request. :param continue_on_error: if set, a Request that causes callback error will be logged only without blocking the further requests. :param return_results: if set, the Documents resulting from all Requests will be returned as a DocumentArray. This is useful when one wants process Responses in bulk instead of using callback. :param kwargs: additional parameters :return: None or DocumentArray containing all response Documents .. warning:: ``target_executor`` uses ``re.match`` for checking if the pattern is matched. ``target_executor=='foo'`` will match both deployments with the name ``foo`` and ``foo_what_ever_suffix``. """ async def _get_results(*args, **kwargs): result = [] c = self.client c.show_progress = show_progress c.continue_on_error = continue_on_error async for resp in c._get_results(*args, **kwargs): if return_results: result.append(resp) if return_results: if c.args.results_as_docarray: docs = [r.data.docs for r in result] if len(docs) < 1: return docs else: return docs[0].reduce_all(docs[1:]) else: return result if (on_always is None) and (on_done is None): return_results = True parameters = _include_results_field_in_param(parameters) return run_async( _get_results, inputs=inputs, on_done=on_done, on_error=on_error, on_always=on_always, exec_endpoint=on, target_executor=target_executor, parameters=parameters, request_size=request_size, **kwargs, )