From 84e2f0af9f5e584ac64feee3fc7d6fb171673d94 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Thu, 11 Apr 2019 11:14:27 +0200 Subject: [PATCH] See #689: added a task to refresh nodeinfo data on known domain periodically --- api/config/settings/common.py | 7 +++++++ api/funkwhale_api/federation/tasks.py | 16 ++++++++++++++++ api/tests/federation/test_tasks.py | 25 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/api/config/settings/common.py b/api/config/settings/common.py index a85a46f97c..be2fa136cf 100644 --- a/api/config/settings/common.py +++ b/api/config/settings/common.py @@ -486,8 +486,15 @@ CELERY_BEAT_SCHEDULE = { "schedule": crontab(minute="0", hour="0"), "options": {"expires": 60 * 60 * 24}, }, + "federation.refresh_nodeinfo_known_nodes": { + "task": "federation.refresh_nodeinfo_known_nodes", + "schedule": crontab(minute="0", hour="*"), + "options": {"expires": 60 * 60}, + }, } +NODEINFO_REFRESH_DELAY = env.int("NODEINFO_REFRESH_DELAY", default=3600 * 24) + JWT_AUTH = { "JWT_ALLOW_REFRESH": True, "JWT_EXPIRATION_DELTA": datetime.timedelta(days=7), diff --git a/api/funkwhale_api/federation/tasks.py b/api/funkwhale_api/federation/tasks.py index 8aebcb27a8..38e8eb6776 100644 --- a/api/funkwhale_api/federation/tasks.py +++ b/api/funkwhale_api/federation/tasks.py @@ -212,6 +212,22 @@ def update_domain_nodeinfo(domain): domain.save(update_fields=["nodeinfo", "nodeinfo_fetch_date", "service_actor"]) +@celery.app.task(name="federation.refresh_nodeinfo_known_nodes") +def refresh_nodeinfo_known_nodes(): + """ + Trigger a node info refresh on all nodes that weren't refreshed since + settings.NODEINFO_REFRESH_DELAY + """ + limit = timezone.now() - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY) + candidates = models.Domain.objects.external().exclude( + nodeinfo_fetch_date__gte=limit + ) + names = candidates.values_list("name", flat=True) + logger.info("Launching periodic nodeinfo refresh on %s domains", len(names)) + for domain_name in names: + update_domain_nodeinfo.delay(domain_name=domain_name) + + def delete_qs(qs): label = qs.model._meta.label result = qs.delete() diff --git a/api/tests/federation/test_tasks.py b/api/tests/federation/test_tasks.py index 5c699cd721..4428484b98 100644 --- a/api/tests/federation/test_tasks.py +++ b/api/tests/federation/test_tasks.py @@ -216,6 +216,31 @@ def test_update_domain_nodeinfo_error(factories, r_mock, now): } +def test_refresh_nodeinfo_known_nodes(settings, factories, mocker, now): + settings.NODEINFO_REFRESH_DELAY = 666 + + refreshed = [ + factories["federation.Domain"](nodeinfo_fetch_date=None), + factories["federation.Domain"]( + nodeinfo_fetch_date=now + - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY + 1) + ), + ] + factories["federation.Domain"]( + nodeinfo_fetch_date=now + - datetime.timedelta(seconds=settings.NODEINFO_REFRESH_DELAY - 1) + ) + + update_domain_nodeinfo = mocker.patch.object(tasks.update_domain_nodeinfo, "delay") + + tasks.refresh_nodeinfo_known_nodes() + + assert update_domain_nodeinfo.call_count == len(refreshed) + + for d in refreshed: + update_domain_nodeinfo.assert_any_call(domain_name=d.name) + + def test_handle_purge_actors(factories, mocker): to_purge = factories["federation.Actor"]() keeped = [ -- GitLab