From 377d6dbed7e7396787cad246b1c94408792bff54 Mon Sep 17 00:00:00 2001 From: Benjamin Braatz Date: Wed, 1 Sep 2021 12:22:46 +0200 Subject: [PATCH] Global cache of validators. --- controlpi/messagebus.py | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/controlpi/messagebus.py b/controlpi/messagebus.py index ed9b6b2..30ec4b8 100644 --- a/controlpi/messagebus.py +++ b/controlpi/messagebus.py @@ -98,6 +98,10 @@ JSONSchema = Union[bool, Dict[str, MessageValue]] MessageCallback = Callable[['Message'], Coroutine[Any, Any, None]] +# Global cache of JSON schema validators: +_validators: Dict[str, jsonschema.Draft7Validator] = {} + + class Message(Dict[str, MessageValue]): """Define arbitrary message. @@ -346,7 +350,6 @@ class MessageTemplate(Dict[str, JSONSchema]): >>> print(t) {'key': {'const': 'value'}} """ - self._validators: Dict[str, jsonschema.Draft7Validator] = {} if init is not None: self.update(init) @@ -425,18 +428,21 @@ class MessageTemplate(Dict[str, JSONSchema]): TypeError: 'schema' is not a valid value in MessageTemplate (not a valid JSON schema). """ + global _validators if not isinstance(key, str): raise TypeError(f"'{key}' is not a valid key in MessageTemplate" " (not a string).") - try: - jsonschema.Draft7Validator.check_schema(value) - # Draft7Validator is hardcoded, because _LATEST_VERSION is - # non-public in jsonschema and we also perhaps do not want to - # upgrade automatically. - except jsonschema.exceptions.SchemaError: - raise TypeError(f"'{value}' is not a valid value in" - " MessageTemplate (not a valid JSON schema).") - self._validators[key] = jsonschema.Draft7Validator(value) + schema_string = json.dumps(value) + if schema_string not in _validators: + try: + jsonschema.Draft7Validator.check_schema(value) + # Draft7Validator is hardcoded, because _LATEST_VERSION is + # non-public in jsonschema and we also perhaps do not want + # to upgrade automatically. + except jsonschema.exceptions.SchemaError: + raise TypeError(f"'{value}' is not a valid value in" + " MessageTemplate (not a valid JSON schema).") + _validators[schema_string] = jsonschema.Draft7Validator(value) super().__setitem__(key, value) def update(self, *args, **kwargs) -> None: @@ -608,7 +614,8 @@ class MessageTemplate(Dict[str, JSONSchema]): if key not in message: return False else: - validator = self._validators[key] + schema_string = json.dumps(self[key]) + validator = _validators[schema_string] for error in validator.iter_errors(message[key]): return False return True @@ -724,7 +731,6 @@ class MessageTemplateRegistry: >>> r = MessageTemplateRegistry() """ - self._validators: Dict[str, jsonschema.Draft7Validator] = {} self._clients: List[str] = [] self._children: Dict[str, Dict[str, MessageTemplateRegistry]] = {} @@ -880,16 +886,17 @@ class MessageTemplateRegistry: {'k1': 'v2', 'k2': 'v1'}: False {'k1': 'v2', 'k2': 'v2'}: True """ + global _validators if client in self._clients: return True for key in self._children: if key in message: for schema_string in self._children[key]: - if schema_string not in self._validators: + if schema_string not in _validators: schema = json.loads(schema_string) - self._validators[schema_string] = \ + _validators[schema_string] = \ jsonschema.Draft7Validator(schema) - validator = self._validators[schema_string] + validator = _validators[schema_string] validated = True for error in validator.iter_errors(message[key]): validated = False @@ -913,6 +920,7 @@ class MessageTemplateRegistry: {'k1': 'v2', 'k2': 'v1'}: [] {'k1': 'v2', 'k2': 'v2'}: ['Client 2'] """ + global _validators result = [] for client in self._clients: if client not in result: @@ -920,11 +928,11 @@ class MessageTemplateRegistry: for key in self._children: if key in message: for schema_string in self._children[key]: - if schema_string not in self._validators: + if schema_string not in _validators: schema = json.loads(schema_string) - self._validators[schema_string] = \ + _validators[schema_string] = \ jsonschema.Draft7Validator(schema) - validator = self._validators[schema_string] + validator = _validators[schema_string] validated = True for error in validator.iter_errors(message[key]): validated = False -- 2.34.1