A common pattern for healthchecks is a low-cost HTTP endpoint, FastStream implements this feature and allows you to create liveness and readiness probes using ASGI feature.
Liveness probes determine when to restart a container. For example: liveness probes could catch a deadlock when an application is running but unable to make progress.
Readiness probes determine when a container is ready to start accepting traffic. This is useful when waiting for an application to perform time-consuming initial tasks, such as establishing network connections, loading files, and warming caches.
This example shows how to implement liveness and readiness probes in FastStream. Readiness probe checks connection to Redis, RabbitMQ and Postgres. Liveness probe checks that app just works.
importasyncioimportloggingfromtypingimportAwaitable,Callable,Anyimportasyncpgimportredis.asyncioasredisimportuvicornfromfaststreamimportFastStreamfromfaststream.asgiimportAsgiResponse,getfromfaststream.rabbitimportRabbitBroker@getasyncdefliveness(scope:dict[str,Any])->AsgiResponse:returnAsgiResponse(b"",status_code=204)defreadiness(broker:RabbitBroker,redis_connection:redis.Redis,postgres_connection:asyncpg.Pool,)->Callable[[dict[str,Any]],Awaitable[AsgiResponse]]:healthy_response=AsgiResponse(b"",204)unhealthy_response=AsgiResponse(b"",500)@getasyncdeffunc(scope:dict[str,Any])->AsgiResponse:try:awaitredis_connection.ping()except(redis.ConnectionError,Exception):logging.exception("Redis not ready")returnunhealthy_responsetry:awaitbroker.ping(timeout=5.0)exceptException:logging.exception("RabbitMQ not ready")returnunhealthy_responsetry:awaitpostgres_connection.fetchval("SELECT 1")except(asyncpg.exceptions.PostgresConnectionError,Exception):logging.exception("Postgres not ready")returnunhealthy_responsereturnhealthy_responsereturnfuncasyncdefmain()->None:redis_connection=redis.Redis(host="redis",port=6379)postgres_connection=awaitasyncpg.create_pool("postgresql://user:password@postgres/postgres")broker=RabbitBroker("amqp://guest:guest@rabbitmq:5672/")app=FastStream(broker)asgi_routes=[("/internal/alive",liveness),("/internal/ready",readiness(broker,redis_connection,postgres_connection)),]uvicorn_config=uvicorn.Config(app.as_asgi(asgi_routes),host="0.0.0.0",port=8000,)server=uvicorn.Server(uvicorn_config)awaitserver.serve()if__name__=="__main__":asyncio.run(main())
But if you use k8s you can use the full power of this feature because you can use live and ready probes together. This is an example of deployment with liveness and readiness probes: