Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: stop the aiohttp app when the metricq HistoryClient is stopped and vice versa #40

Merged
merged 1 commit into from
Sep 27, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion metricq_grafana/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import asyncio
import logging
import traceback
from contextlib import suppress

import click

Expand Down Expand Up @@ -33,9 +34,40 @@ async def start_background_tasks(app):
)
await app["history_client"].connect()

async def watchdog():
try:
await app["history_client"].stopped()
except Exception as e:
logger.error("history client encountered an error: {}", e)

# The "graceful" way to stop an aiohttp runner is
# about as graceful as an elephant seal, but it works.
# It's also a private API, but what can we do?
# https://github.com/aio-libs/aiohttp/issues/2950
# This is exactly what the signal handlers do.
# We could maybe be a little bit more graceful by
# running app.shutdown() and app.cleanup() before this,
# but then we get recursive mess again.
# And just runnign shutdown() and cleanup() won't do it either.
# See also:
# https://github.com/aio-libs/aiohttp/issues/3638#issuecomment-621256659
# Note that we suppress the Exception later so it doesn't end
# up as a dreaded "Task exception was never retrieved"
raise web.GracefulExit()

app["history_client_watchdog"] = app.loop.create_task(watchdog())


async def cleanup_background_tasks(app):
pass
logger.debug("cleanup_background_tasks called")
with suppress(KeyError):
app["history_client_watchdog"].cancel()
# If it was the watchdog who caused the "GracefulExit"
# Then we can suppress it here, it has already done it's deed
with suppress(web.GracefulExit):
await app["history_client_watchdog"]
with suppress(KeyError):
await app["history_client"].stop()


def create_app(loop, token, management_url, management_exchange, cors_origin):
Expand Down