def test_grpc_gateway_runtime_init_close(): deployment0_port = random_port() deployment1_port = random_port() port_expose = random_port() def _create_runtime(): with GRPCGatewayRuntime(set_gateway_parser().parse_args([ '--port-expose', str(port_expose), '--graph-description', '{"start-gateway": ["deployment0"], "deployment0": ["end-gateway"]}', '--deployments-addresses', '{"deployment0": ["0.0.0.0:' + f'{deployment0_port}' + '", "0.0.0.0:' + f'{deployment1_port}' + '"]}', ])) as runtime: runtime.run_forever() p = multiprocessing.Process(target=_create_runtime) p.start() time.sleep(1.0) assert AsyncNewLoopRuntime.is_ready( ctrl_address=f'127.0.0.1:{port_expose}') p.terminate() p.join() assert p.exitcode == 0
async def test_decorator_monitoring(port_generator): from jina import monitor class DummyExecutor(Executor): @requests def foo(self, docs, **kwargs): self._proces(docs) self.process_2(docs) @monitor(name='metrics_name', documentation='metrics description') def _proces(self, docs): ... @monitor() def process_2(self, docs): ... port = port_generator() args = set_pod_parser().parse_args([ '--monitoring', '--port-monitoring', str(port), '--uses', 'DummyExecutor' ]) cancel_event = multiprocessing.Event() def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_thread.start() assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=5.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=5.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) await GrpcConnectionPool.send_request_async(_create_test_data_message(), f'{args.host}:{args.port}', timeout=1.0) resp = req.get(f'http://localhost:{port}/') assert f'jina_metrics_name_count{{runtime_name="None"}} 1.0' in str( resp.content) cancel_event.set() runtime_thread.join() assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
async def test_grpc_gateway_runtime_reflection(): deployment0_port = random_port() deployment1_port = random_port() port = random_port() def _create_runtime(): with GRPCGatewayRuntime(set_gateway_parser().parse_args([ '--port', str(port), '--graph-description', '{"start-gateway": ["deployment0"], "deployment0": ["end-gateway"]}', '--deployments-addresses', '{"deployment0": ["0.0.0.0:' + f'{deployment0_port}' + '", "0.0.0.0:' + f'{deployment1_port}' + '"]}', ])) as runtime: runtime.run_forever() p = multiprocessing.Process(target=_create_runtime) p.start() time.sleep(1.0) assert AsyncNewLoopRuntime.is_ready(ctrl_address=f'127.0.0.1:{port}') async with grpc.aio.insecure_channel(f'127.0.0.1:{port}') as channel: service_names = await GrpcConnectionPool.get_available_services(channel ) assert all(service_name in service_names for service_name in ['jina.JinaRPC']) p.terminate() p.join() assert p.exitcode == 0
async def test_worker_runtime_reflection(): args = set_pod_parser().parse_args([]) cancel_event = multiprocessing.Event() def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_thread.start() assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=3.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) async with grpc.aio.insecure_channel( f'{args.host}:{args.port}') as channel: service_names = await GrpcConnectionPool.get_available_services(channel ) assert all(service_name in service_names for service_name in [ 'jina.JinaDataRequestRPC', 'jina.JinaSingleDataRequestRPC', ]) cancel_event.set() runtime_thread.join() assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
def check_health_pod(addr: str): """check if a pods is healthy :param addr: the address on which the pod is serving ex : localhost:1234 """ from jina.serve.runtimes.asyncio import AsyncNewLoopRuntime is_ready = AsyncNewLoopRuntime.is_ready(addr) if not is_ready: raise Exception('Pod is unhealthy') print('The Pod is healthy')
async def test_worker_runtime_slow_init_exec(): args = set_pod_parser().parse_args(['--uses', 'SlowInitExecutor']) cancel_event = multiprocessing.Event() def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_started = time.time() runtime_thread.start() # wait a bit to the worker runtime has a chance to finish some things, but not the Executor init (5 secs) time.sleep(1.0) # try to connect a TCP socket to the gRPC server # this should only succeed after the Executor is ready, which should be after 5 seconds with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: connected = False while not connected: try: s.connect((args.host, args.port)) connected = True except ConnectionRefusedError: time.sleep(0.2) # Executor sleeps 5 seconds, so at least 5 seconds need to have elapsed here assert time.time() - runtime_started > 5.0 assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=3.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) result = await GrpcConnectionPool.send_request_async( _create_test_data_message(), f'{args.host}:{args.port}', timeout=1.0 ) assert len(result.docs) == 1 cancel_event.set() runtime_thread.join() assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
async def test_worker_runtime_slow_async_exec(uses): args = set_pod_parser().parse_args(['--uses', uses]) cancel_event = multiprocessing.Event() def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_thread.start() assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=5.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) target = f'{args.host}:{args.port}' results = [] async with grpc.aio.insecure_channel( target, options=GrpcConnectionPool.get_default_grpc_options(), ) as channel: stub = jina_pb2_grpc.JinaSingleDataRequestRPCStub(channel) tasks = [] for i in range(10): async def task_wrapper(): return await stub.process_single_data( _create_test_data_message()) tasks.append(asyncio.create_task(task_wrapper())) for future in asyncio.as_completed(tasks): t = await future results.append(t.docs[0].text) cancel_event.set() runtime_thread.join() if uses == 'AsyncSlowNewDocsExecutor': assert results == ['1', '3', '5', '7', '9', '2', '4', '6', '8', '10'] else: assert results == ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
def test_error_in_worker_runtime(monkeypatch): args = set_pod_parser().parse_args([]) cancel_event = multiprocessing.Event() def fail(*args, **kwargs): raise RuntimeError('intentional error') monkeypatch.setattr(DataRequestHandler, 'handle', fail) def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_thread.start() assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=5.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) target = f'{args.host}:{args.port}' with grpc.insecure_channel( target, options=GrpcConnectionPool.get_default_grpc_options(), ) as channel: stub = jina_pb2_grpc.JinaSingleDataRequestRPCStub(channel) response, call = stub.process_single_data.with_call( _create_test_data_message()) assert response.header.status.code == jina_pb2.StatusProto.ERROR assert 'is-error' in dict(call.trailing_metadata()) cancel_event.set() runtime_thread.join() assert response assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
def test_worker_runtime(): args = set_pod_parser().parse_args([]) cancel_event = multiprocessing.Event() def start_runtime(args, cancel_event): with WorkerRuntime(args, cancel_event=cancel_event) as runtime: runtime.run_forever() runtime_thread = Process( target=start_runtime, args=(args, cancel_event), daemon=True, ) runtime_thread.start() assert AsyncNewLoopRuntime.wait_for_ready_or_shutdown( timeout=5.0, ctrl_address=f'{args.host}:{args.port}', ready_or_shutdown_event=Event(), ) target = f'{args.host}:{args.port}' with grpc.insecure_channel( target, options=GrpcConnectionPool.get_default_grpc_options(), ) as channel: stub = jina_pb2_grpc.JinaSingleDataRequestRPCStub(channel) response, call = stub.process_single_data.with_call( _create_test_data_message()) cancel_event.set() runtime_thread.join() assert response assert not AsyncNewLoopRuntime.is_ready(f'{args.host}:{args.port}')
def _is_ready(): return AsyncNewLoopRuntime.is_ready(runtime_ctrl_address)