Cache literal sync filter validation (#17186)
The sliding sync proxy (amongst other things) use literal json blobs as filters, and repeatedly validating them takes a bunch of CPU.
This commit is contained in:
parent
ebe77381b0
commit
284d85dee3
|
@ -0,0 +1 @@
|
|||
Cache literal sync filter validation for performance.
|
|
@ -47,6 +47,7 @@ from synapse.http.site import SynapseRequest
|
|||
from synapse.logging.opentracing import trace_with_opname
|
||||
from synapse.types import JsonDict, Requester, StreamToken
|
||||
from synapse.util import json_decoder
|
||||
from synapse.util.caches.lrucache import LruCache
|
||||
|
||||
from ._base import client_patterns, set_timeline_upper_limit
|
||||
|
||||
|
@ -110,6 +111,11 @@ class SyncRestServlet(RestServlet):
|
|||
self._msc2654_enabled = hs.config.experimental.msc2654_enabled
|
||||
self._msc3773_enabled = hs.config.experimental.msc3773_enabled
|
||||
|
||||
self._json_filter_cache: LruCache[str, bool] = LruCache(
|
||||
max_size=1000,
|
||||
cache_name="sync_valid_filter",
|
||||
)
|
||||
|
||||
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
# This will always be set by the time Twisted calls us.
|
||||
assert request.args is not None
|
||||
|
@ -177,7 +183,13 @@ class SyncRestServlet(RestServlet):
|
|||
filter_object = json_decoder.decode(filter_id)
|
||||
except Exception:
|
||||
raise SynapseError(400, "Invalid filter JSON", errcode=Codes.NOT_JSON)
|
||||
|
||||
# We cache the validation, as this can get quite expensive if people use
|
||||
# a literal json blob as a query param.
|
||||
if not self._json_filter_cache.get(filter_id):
|
||||
self.filtering.check_valid_filter(filter_object)
|
||||
self._json_filter_cache[filter_id] = True
|
||||
|
||||
set_timeline_upper_limit(
|
||||
filter_object, self.hs.config.server.filter_timeline_limit
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue