Trwała wieloprocesowa współużytkowana pamięć podręczna w Pythonie ze stdlib lub minimalnymi zależnościami

Właśnie wypróbowałem Pythonaodłożyć na półkę moduł jako trwała pamięć podręczna dla danych pobranych z usługi zewnętrznej.Kompletny przykład jest tutaj.

Zastanawiałem się, jakie byłoby najlepsze podejście, jeśli chcę uczynić ten proces wieloprocesowy bezpiecznym? Wiem o redis, memcached i takich „prawdziwych rozwiązaniach”, ale chciałbym używać tylko części standardowej biblioteki Pythona lub bardzo minimalnych zależności, aby mój kod był zwarty i nie wprowadzał niepotrzebnej złożoności podczas uruchamiania kodu w pojedynczym procesie - model z pojedynczą nicią.

Łatwo jest wymyślić rozwiązanie jednoprocesowe, ale to nie działa dobrze w obecnych czasach uruchamiania Pythona. W szczególności problemem może być środowisko Apache + mod_wsgi

Tylko jeden proces jednorazowo aktualizuje buforowane dane (jakoś blokuje plik?)

Inne procesy wykorzystują buforowane dane w trakcie aktualizacji

Jeśli w procesie nie uda się zaktualizować buforowanych danych, naliczana jest kara w wysokości N minut, zanim inny proces będzie mógł spróbować ponownie (aby zapobiecgrzmiące stado i takie) - jak zasygnalizować to między procesami mod_wsgi

Nie używasz do tego żadnych „ciężkich narzędzi”, tylko standardowe biblioteki Pythona i UNIX

Również jeśli jakiś pakiet PyPi robi to bez zewnętrznych zależności, daj mi znać. Mile widziane są alternatywne podejścia i zalecenia, takie jak „po prostu użyj sqlite”.

Przykład:

import datetime
import os
import shelve
import logging


logger = logging.getLogger(__name__)


class Converter:

    def __init__(self, fpath):
        self.last_updated = None
        self.data = None

        self.data = shelve.open(fpath)

        if os.path.exists(fpath):
            self.last_updated = datetime.datetime.fromtimestamp(os.path.getmtime(fpath))

    def convert(self, source, target, amount, update=True, determiner="24h_avg"):
        # Do something with cached data
        pass

    def is_up_to_date(self):
        if not self.last_updated:
            return False

        return datetime.datetime.now() < self.last_updated + self.refresh_delay

    def update(self):
        try:
            # Update data from the external server
            self.last_updated = datetime.datetime.now()
            self.data.sync()
        except Exception as e:
            logger.error("Could not refresh market data: %s %s", self.api_url, e)
            logger.exception(e)

questionAnswers(3)

yourAnswerToTheQuestion