diff --git a/conf/init/service/gunicorn_registry/run b/conf/init/service/gunicorn_registry/run index 3b38ea155..25e9dd524 100755 --- a/conf/init/service/gunicorn_registry/run +++ b/conf/init/service/gunicorn_registry/run @@ -4,6 +4,7 @@ echo 'Starting gunicon' QUAYPATH=${QUAYPATH:-"."} QUAYCONF=${QUAYCONF:-"$QUAYPATH/conf"} +DB_CONNECTION_POOLING=${DB_CONNECTION_POOLING:-"true"} cd ${QUAYDIR:-"/"} PYTHONPATH=$QUAYPATH nice -n 10 venv/bin/gunicorn -c $QUAYCONF/gunicorn_registry.py registry:application diff --git a/data/database.py b/data/database.py index 5933005f7..8314c8fb2 100644 --- a/data/database.py +++ b/data/database.py @@ -6,9 +6,10 @@ import string import sys import time import uuid +import os from contextlib import contextmanager -from collections import defaultdict +from collections import defaultdict, namedtuple from datetime import datetime from random import SystemRandom @@ -17,6 +18,7 @@ import toposort from enum import Enum from peewee import * from playhouse.shortcuts import RetryOperationalError +from playhouse.pool import PooledMySQLDatabase, PooledPostgresqlDatabase, PooledSqliteDatabase from sqlalchemy.engine.url import make_url @@ -39,13 +41,14 @@ DEFAULT_DB_CONNECT_TIMEOUT = 10 # seconds # image has not yet been scanned. IMAGE_NOT_SCANNED_ENGINE_VERSION = -1 +schemedriver = namedtuple('schemedriver', ['driver', 'pooled_driver']) _SCHEME_DRIVERS = { - 'mysql': MySQLDatabase, - 'mysql+pymysql': MySQLDatabase, - 'sqlite': SqliteDatabase, - 'postgresql': PostgresqlDatabase, - 'postgresql+psycopg2': PostgresqlDatabase, + 'mysql': schemedriver(MySQLDatabase, PooledMySQLDatabase), + 'mysql+pymysql': schemedriver(MySQLDatabase, PooledMySQLDatabase), + 'sqlite': schemedriver(SqliteDatabase, PooledSqliteDatabase), + 'postgresql': schemedriver(PostgresqlDatabase, PooledPostgresqlDatabase), + 'postgresql+psycopg2': schemedriver(PostgresqlDatabase, PooledPostgresqlDatabase), } @@ -269,7 +272,12 @@ def _db_from_url(url, db_kwargs, connect_timeout=DEFAULT_DB_CONNECT_TIMEOUT): if parsed_url.drivername != 'sqlite': db_kwargs['connect_timeout'] = db_kwargs.get('connect_timeout', connect_timeout) - driver = _SCHEME_DRIVERS[parsed_url.drivername] + drivers = _SCHEME_DRIVERS[parsed_url.drivername] + driver = drivers.driver + if os.getenv('DB_CONNECTION_POOLING', 'false').lower() == 'true': + logger.debug('Connection pooling enabled') + driver = drivers.pooled_driver + wrapped_driver = _wrap_for_retry(driver) return wrapped_driver(parsed_url.database, **db_kwargs)