diff --git a/conda-store-server/conda_store_server/app.py b/conda-store-server/conda_store_server/app.py index 5a14f6d2f..d282e330a 100644 --- a/conda-store-server/conda_store_server/app.py +++ b/conda-store-server/conda_store_server/app.py @@ -107,10 +107,10 @@ def session_factory(self): @property def db(self): - if hasattr(self, "_db"): - return self._db - self._db = self.session_factory() - return self._db + # we are using a scoped_session which always returns the same + # session if within the same thread + # https://docs.sqlalchemy.org/en/14/orm/contextual.html + return self.session_factory() @property def configuration(self): diff --git a/conda-store-server/conda_store_server/orm.py b/conda-store-server/conda_store_server/orm.py index 6c72e468d..09c6fa8d6 100644 --- a/conda-store-server/conda_store_server/orm.py +++ b/conda-store-server/conda_store_server/orm.py @@ -15,7 +15,7 @@ UniqueConstraint, ForeignKey, ) -from sqlalchemy.orm import sessionmaker, relationship +from sqlalchemy.orm import sessionmaker, relationship, scoped_session from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import create_engine @@ -296,5 +296,5 @@ def new_session_factory(url="sqlite:///:memory:", reset=False, **kwargs): Base.metadata.create_all(engine) - session_factory = sessionmaker(bind=engine) + session_factory = scoped_session(sessionmaker(bind=engine)) return session_factory diff --git a/conda-store-server/conda_store_server/server/app.py b/conda-store-server/conda_store_server/server/app.py index 15ee41d7a..50aaee46a 100644 --- a/conda-store-server/conda_store_server/server/app.py +++ b/conda-store-server/conda_store_server/server/app.py @@ -85,6 +85,13 @@ def start(self): app.conda_store = CondaStore(parent=self, log=self.log) app.authentication = self.authentication_class(parent=self, log=self.log) + @app.after_request + def after_request_function(response): + # force a new session on next request + # since sessions are thread local + app.conda_store.session_factory.remove() + return response + # add dynamic routes for route, method, func in app.authentication.routes: app.add_url_rule(route, func.__name__, func, methods=[method])