From 4bf91ffa80059a6987d1403933930442105f41bd Mon Sep 17 00:00:00 2001 From: Thomas Sileo Date: Sat, 10 Aug 2019 11:13:43 +0200 Subject: [PATCH] Add a way to disable caching, and start "versionning" actor in caches --- core/activitypub.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/core/activitypub.py b/core/activitypub.py index 7ec62a8..a548d4e 100644 --- a/core/activitypub.py +++ b/core/activitypub.py @@ -2,12 +2,14 @@ import binascii import hashlib import logging import os +from contextlib import contextmanager from datetime import datetime from datetime import timezone from typing import Any from typing import Dict from typing import List from typing import Optional +from typing import Iterator from urllib.parse import urljoin from urllib.parse import urlparse @@ -36,10 +38,22 @@ logger = logging.getLogger(__name__) _NewMeta = Dict[str, Any] +_ACTIVITY_CACHE_ENABLED = True ACTORS_CACHE = LRUCache(maxsize=256) MY_PERSON = ap.Person(**ME) +@contextmanager +def no_cache() -> Iterator[None]: + """Context manager for disabling the "DB cache" when fetching AP activities.""" + global _ACTIVITY_CACHE_ENABLED + _ACTIVITY_CACHE_ENABLED = False + try: + yield + finally: + _ACTIVITY_CACHE_ENABLED = True + + def _remove_id(doc: ap.ObjectType) -> ap.ObjectType: """Helper for removing MongoDB's `_id` field.""" doc = doc.copy() @@ -54,6 +68,22 @@ def _answer_key(choice: str) -> str: return h.hexdigest() +def _actor_hash(actor: ap.ActivityType) -> str: + """Used to know when to update the meta actor cache, like an "actor version".""" + h = hashlib.new("sha1") + h.update(actor.id.encode()) + h.update((actor.name or "").encode()) + h.update((actor.preferredUsername or "").encode()) + h.update((actor.summary or "").encode()) + h.update((actor.url or "").encode()) + key = actor.get_key() + h.update(key.pubkey_pem.encode()) + h.update(key.key_id().encode()) + if isinstance(actor.icon, dict) and "url" in actor.icon: + h.update(actor.icon["url"].encode()) + return h.hexdigest() + + def _is_local_reply(create: ap.Create) -> bool: for dest in _to_list(create.to or []): if dest.startswith(BASE_URL): @@ -326,13 +356,13 @@ class MicroblogPubBackend(Backend): return super().fetch_iri(iri) def fetch_iri(self, iri: str, no_cache=False) -> ap.ObjectType: - if not no_cache: + if not no_cache and _ACTIVITY_CACHE_ENABLED: # Fetch the activity by checking the local DB first data = self._fetch_iri(iri) + logger.debug(f"_fetch_iri({iri!r}) == {data!r}") else: data = super().fetch_iri(iri) - - logger.debug(f"_fetch_iri({iri!r}) == {data!r}") + logger.debug(f"fetch_iri({iri!r}) == {data!r}") return data