mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-14 02:59:45 +08:00
76 lines
2.8 KiB
Python
76 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import sqlalchemy.event
|
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
|
from sqlalchemy.pool import NullPool
|
|
|
|
from module_build_service import conf
|
|
from module_build_service.models import session_before_commit_handlers
|
|
|
|
__all__ = ("db_session",)
|
|
|
|
|
|
def _setup_event_listeners(db_session):
|
|
"""
|
|
Starts listening for events related to the database session.
|
|
"""
|
|
if not sqlalchemy.event.contains(db_session, "before_commit", session_before_commit_handlers):
|
|
sqlalchemy.event.listen(db_session, "before_commit", session_before_commit_handlers)
|
|
|
|
# initialize DB event listeners from the monitor module
|
|
from module_build_service.monitor import db_hook_event_listeners
|
|
|
|
db_hook_event_listeners(db_session.bind.engine)
|
|
|
|
|
|
def apply_engine_options(conf):
|
|
options = {
|
|
"configuration": {"sqlalchemy.url": conf.sqlalchemy_database_uri},
|
|
}
|
|
if conf.sqlalchemy_database_uri.startswith("sqlite://"):
|
|
options.update({
|
|
# For local module build, MBS is actually a multi-threaded
|
|
# application. The command submitting a module build runs in its
|
|
# own thread, and the backend build workflow, implemented as a
|
|
# fedmsg consumer on top of fedmsg-hub, runs in separate threads.
|
|
# So, disable this option in order to allow accessing data which
|
|
# was written from another thread.
|
|
"connect_args": {"check_same_thread": False},
|
|
|
|
# Both local module build and running tests requires a file-based
|
|
# SQLite database, we do not use a connection pool for these two
|
|
# scenarios.
|
|
"poolclass": NullPool,
|
|
})
|
|
else:
|
|
# TODO - we could use ZopeTransactionExtension() here some day for
|
|
# improved safety on the backend.
|
|
pool_options = {}
|
|
|
|
# Apply pool options SQLALCHEMY_* set in MBS config.
|
|
# Abbrev sa stands for SQLAlchemy.
|
|
def apply_mbs_option(mbs_config_key, sa_config_key):
|
|
value = getattr(conf, mbs_config_key, None)
|
|
if value is not None:
|
|
pool_options[sa_config_key] = value
|
|
|
|
apply_mbs_option("sqlalchemy_pool_size", "pool_size")
|
|
apply_mbs_option("sqlalchemy_pool_timeout", "pool_timeout")
|
|
apply_mbs_option("sqlalchemy_pool_recycle", "pool_recycle")
|
|
apply_mbs_option("sqlalchemy_max_overflow", "max_overflow")
|
|
|
|
options.update(pool_options)
|
|
|
|
return options
|
|
|
|
|
|
engine_opts = apply_engine_options(conf)
|
|
engine = sqlalchemy.engine_from_config(**engine_opts)
|
|
session_factory = sessionmaker(bind=engine)
|
|
|
|
# This is the global, singleton database Session that could be used to operate
|
|
# database queries.
|
|
db_session = scoped_session(session_factory)
|
|
_setup_event_listeners(db_session)
|