diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 01fa4ce9..7e36709d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -35,6 +35,7 @@ Bug Fixes :: * Add python version requirement on setup.py (#586) [jason-the-j] + * Add a thread lock to avoid concurrent schema construction. (#545) [peter-doggart] * Fix Nested field schema generation for nullable fields. (#638) [peter-doggart] * Fix reference resolution for definitions in schema. (#553) [peter-doggart] diff --git a/flask_restx/api.py b/flask_restx/api.py index 83ad9ec9..4f758714 100644 --- a/flask_restx/api.py +++ b/flask_restx/api.py @@ -2,6 +2,7 @@ import inspect from itertools import chain import logging +import threading import operator import re import sys @@ -161,6 +162,7 @@ def __init__( } ) self._schema = None + self._schema_lock = threading.Lock() self.models = {} self._refresolver = None self.format_checker = format_checker @@ -567,14 +569,17 @@ def __schema__(self): :returns dict: the schema as a serializable dict """ if not self._schema: - try: - self._schema = Swagger(self).as_dict() - except Exception: - # Log the source exception for debugging purpose - # and return an error message - msg = "Unable to render schema" - log.exception(msg) # This will provide a full traceback - return {"error": msg} + # Guard schema initialization to avoid concurrent construction on first access + with self._schema_lock: + if not self._schema: + try: + self._schema = Swagger(self).as_dict() + except Exception: + # Log the source exception for debugging purpose + # and return an error message + msg = "Unable to render schema" + log.exception(msg) # This will provide a full traceback + return {"error": msg} return self._schema @property