Content
API
API
API
API
FRONT API
FRONT APP
Text
SERVEUR WEB
Résultat
Internet
URL
CACHE
for item in models:
for subitem in item.subitems:
for subsubitem in subitem.subitems:
invalid_cache(subsubitem)
for subsubitem in subitem.other_subitems:
invalid_cache(subsubitem)
invalid_cache(subitem)
invalid_cache(item)
😭
🤔
?
"Site-1 Category-1 Category-2 Category-3"
def surrogate_keys_tween(request):
request.surrogate_keys = set()
response = handler(request)
response.headers["Surrogate-Key"] = " ".join(request.surrogate_keys)
return response
from pyramid.threadlocal import get_current_request
from sqlalchemy import event
@event.listens_for(SomeSessionOrFactory, 'loaded_as_persistent')
def loaded_as_persistent(session, instance):
key = f"{instance.__class__.__name__}-{instance.id}"
get_current_request().surrogate_keys.add(key)
Key | Value |
---|---|
/site | [{id: 1, ...}, {id: 2, ...}, ...] |
Key | Value |
---|---|
Site-1 | ["/site"] |
Site-2 | ["/site"] |
Surrogate-Key: Site-1 Site-2
/site
Key | Value |
---|---|
/site | [{id: 1, ...}, {id: 2, ...}, ...] |
/site/1 | {id: 1, ...} |
Site-1 | ["/site", "/site/1"] |
Site-2 | ["/site"] |
Category-1 | ["/site/1"] |
Category-2 | ["/site/1"] |
Category-3 | ["/site/1"] |
Surrogate-Key: Site-1 Category-1 Category-2 Category-3
/site/1
Key | Value |
---|---|
/site/ | [{id: 1, ...}, {id: 2, ...}, ...] |
/site/1 | {id: 1, ...} |
Site-1 | ["/site", "/site/1"] |
Site-2 | ["/site"] |
Category-1 | ["/site/1"] |
Category-2 | ["/site/1"] |
Category-3 | ["/site/1"] |
surrogate key : Site-1
import itertools
from monprojet.cache import redis_client, redis_paginator, scan_iter, sscan_iter
def store_response(path, surrogate_keys, response):
pipe = redis_client.pipeline()
for surrogate_key in surrogate_keys:
pipe.sadd(f"associations:{surrogate_key}", path)
pipe.set(f"responses:{path}", pickle.dumps(response))
pipe.execute()
def invalid(surrogate_keys_str):
surrogate_keys = surrogate_keys_str.split(" ")
pipe = redis_client.pipeline()
association_keys = [
association_key.decode("utf-8")
for surrogate_key in surrogate_keys
for association_key in scan_iter(0, match=f"associations:{surrogate_key}")
]
response_keys = (
"responses:{}".format(key.decode("utf-8"))
for asso in association_keys
for key in sscan_iter(asso, 0)
)
for key in set(itertools.chain(association_keys, response_keys)):
pipe.delete(key)
pipe.execute()
from sqlalalchemy import event
@db.event.listens_for(SomeSessionOrFactory, "after_begin")
def handle_after_begin(session, transaction, connection):
session.surrogate_keys = set()
@db.event.listens_for(SomeSessionOrFactory, "before_flush")
def handle_before_flush(session, flush_context, instances):
session.surrogate_keys |= get_surrogate_keys_for_modified_objects(session)
@db.event.listens_for(SomeSessionOrFactory, "before_commit")
def handle_before_commit(session):
session.surrogate_keys |= get_surrogate_keys_for_modified_objects(session)
@db.event.listens_for(SomeSessionOrFactory, "after_commit")
def handle_after_commit(session):
invalid(" ".join(sorted(session.surrogate_keys)))
def get_surrogate_keys_for_modified_objects(session):
return (
set(f"{instance.__class__.__name__}-{instance.id}" for instance in session.new)
| set(f"{instance.__class__.__name__}-{instance.id}" for instance in session.dirty)
| set(f"{instance.__class__.__name__}-{instance.id}" for instance in session.deleted)
)
@rcommande