123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- # Copyright 2020 The gRPC authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- """The Python implementation of the GRPC helloworld.Greeter server."""
- import argparse
- from concurrent import futures
- import logging
- import socket
- import grpc
- from grpc_health.v1 import health
- from grpc_health.v1 import health_pb2
- from grpc_health.v1 import health_pb2_grpc
- from grpc_reflection.v1alpha import reflection
- import helloworld_pb2
- import helloworld_pb2_grpc
- _DESCRIPTION = "A general purpose phony server."
- _LISTEN_HOST = "0.0.0.0"
- _THREAD_POOL_SIZE = 256
- logger = logging.getLogger()
- console_handler = logging.StreamHandler()
- formatter = logging.Formatter(fmt='%(asctime)s: %(levelname)-8s %(message)s')
- console_handler.setFormatter(formatter)
- logger.addHandler(console_handler)
- class Greeter(helloworld_pb2_grpc.GreeterServicer):
- def __init__(self, hostname: str):
- self._hostname = hostname if hostname else socket.gethostname()
- def SayHello(self, request: helloworld_pb2.HelloRequest,
- context: grpc.ServicerContext) -> helloworld_pb2.HelloReply:
- return helloworld_pb2.HelloReply(
- message=f"Hello {request.name} from {self._hostname}!")
- def _configure_maintenance_server(server: grpc.Server,
- maintenance_port: int) -> None:
- listen_address = f"{_LISTEN_HOST}:{maintenance_port}"
- server.add_insecure_port(listen_address)
- # Create a health check servicer. We use the non-blocking implementation
- # to avoid thread starvation.
- health_servicer = health.HealthServicer(
- experimental_non_blocking=True,
- experimental_thread_pool=futures.ThreadPoolExecutor(
- max_workers=_THREAD_POOL_SIZE))
- # Create a tuple of all of the services we want to export via reflection.
- services = tuple(
- service.full_name
- for service in helloworld_pb2.DESCRIPTOR.services_by_name.values()) + (
- reflection.SERVICE_NAME, health.SERVICE_NAME)
- # Mark all services as healthy.
- health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server)
- for service in services:
- health_servicer.set(service, health_pb2.HealthCheckResponse.SERVING)
- reflection.enable_server_reflection(services, server)
- def _configure_greeter_server(server: grpc.Server, port: int, secure_mode: bool,
- hostname) -> None:
- # Add the application servicer to the server.
- helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(hostname), server)
- listen_address = f"{_LISTEN_HOST}:{port}"
- if not secure_mode:
- server.add_insecure_port(listen_address)
- else:
- # Use xDS credentials.
- logger.info("Running with xDS Server credentials")
- # Fall back to insecure credentials.
- server_fallback_creds = grpc.insecure_server_credentials()
- server_creds = grpc.xds_server_credentials(server_fallback_creds)
- server.add_secure_port(listen_address, server_creds)
- def serve(port: int, hostname: str, maintenance_port: int,
- secure_mode: bool) -> None:
- if port == maintenance_port:
- # If maintenance port and port are the same, start a single server.
- server = grpc.server(
- futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE))
- _configure_greeter_server(server, port, secure_mode, hostname)
- _configure_maintenance_server(server, maintenance_port)
- server.start()
- logger.info("Greeter server listening on port %d", port)
- logger.info("Maintenance server listening on port %d", maintenance_port)
- server.wait_for_termination()
- else:
- # Otherwise, start two different servers.
- greeter_server = grpc.server(
- futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE),
- xds=secure_mode)
- _configure_greeter_server(greeter_server, port, secure_mode, hostname)
- greeter_server.start()
- logger.info("Greeter server listening on port %d", port)
- maintenance_server = grpc.server(
- futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE))
- _configure_maintenance_server(maintenance_server, maintenance_port)
- maintenance_server.start()
- logger.info("Maintenance server listening on port %d", maintenance_port)
- greeter_server.wait_for_termination()
- maintenance_server.wait_for_termination()
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description=_DESCRIPTION)
- parser.add_argument("port",
- default=50051,
- type=int,
- nargs="?",
- help="The port on which to listen.")
- parser.add_argument("hostname",
- type=str,
- default=None,
- nargs="?",
- help="The name clients will see in responses.")
- parser.add_argument(
- "--xds-creds",
- action="store_true",
- help="If specified, uses xDS credentials to connect to the server.")
- args = parser.parse_args()
- logging.basicConfig()
- logger.setLevel(logging.INFO)
- serve(args.port, args.hostname, args.port + 1, args.xds_creds)
|