From ef078a4ab56379e106433848bd425da9e4e27c21 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 23 Jun 2022 19:40:17 +0530 Subject: [PATCH] refactor(db-read_only): Track conn type in Database instance --- frappe/__init__.py | 4 +++- frappe/database/__init__.py | 10 +++++++--- frappe/database/database.py | 12 +++++++++++- frappe/database/mariadb/database.py | 20 +++++++++----------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index e61b1829fa..09248fa99f 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -279,7 +279,9 @@ def connect_replica(): user = local.conf.replica_db_name password = local.conf.replica_db_password - local.replica_db = get_db(host=local.conf.replica_host, user=user, password=password, port=port) + local.replica_db = get_db( + host=local.conf.replica_host, user=user, password=password, port=port, read_only=True + ) # swap db connections local.primary_db = local.db diff --git a/frappe/database/__init__.py b/frappe/database/__init__.py index 7de3fabf01..423442d344 100644 --- a/frappe/database/__init__.py +++ b/frappe/database/__init__.py @@ -39,17 +39,21 @@ def drop_user_and_database(db_name, root_login=None, root_password=None): ) -def get_db(host=None, user=None, password=None, port=None): +def get_db(host=None, user=None, password=None, port=None, read_only=False): import frappe if frappe.conf.db_type == "postgres": import frappe.database.postgres.database - return frappe.database.postgres.database.PostgresDatabase(host, user, password, port=port) + return frappe.database.postgres.database.PostgresDatabase( + host, user, password, port=port, read_only=read_only + ) else: import frappe.database.mariadb.database - return frappe.database.mariadb.database.MariaDBDatabase(host, user, password, port=port) + return frappe.database.mariadb.database.MariaDBDatabase( + host, user, password, port=port, read_only=read_only + ) def setup_help_database(help_db_name): diff --git a/frappe/database/database.py b/frappe/database/database.py index 73460614cb..f3f539b792 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -52,12 +52,22 @@ class Database(object): class InvalidColumnName(frappe.ValidationError): pass - def __init__(self, host=None, user=None, password=None, ac_name=None, use_default=0, port=None): + def __init__( + self, + host=None, + user=None, + password=None, + ac_name=None, + use_default=0, + port=None, + read_only=False, + ): self.setup_type_map() self.host = host or frappe.conf.db_host or "127.0.0.1" self.port = port or frappe.conf.db_port or "" self.user = user or frappe.conf.db_name self.db_name = frappe.conf.db_name + self.read_only = read_only # Uses READ ONLY connection if set self._conn = None if ac_name: diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index c444e492a2..c255d40d28 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -133,12 +133,10 @@ class MariaDBConnectionUtil: self.close_connection_pools() return self.create_connection() - read_only = frappe.conf.read_from_replica and frappe.conf.replica_host - if frappe.local.site not in _SITE_POOLS: - site_pool = self.create_connection_pool(read_only=read_only) + site_pool = self.create_connection_pool() else: - site_pool = self.get_connection_pool(read_only=read_only) + site_pool = self.get_connection_pool() try: conn = site_pool.get_connection() @@ -165,26 +163,26 @@ class MariaDBConnectionUtil: pass _SITE_POOLS.pop(frappe.local.site, None) - def get_pool_name(self, read_only=False) -> str: - pool_type = "read-only" if read_only else "default" + def get_pool_name(self) -> str: + pool_type = "read-only" if self.read_only else "default" return f"{frappe.local.site}-{pool_type}" - def get_connection_pool(self, read_only=False) -> "ConnectionPool": + def get_connection_pool(self) -> "ConnectionPool": """Return MariaDB connection pool object. If `read_only` is True, return a read only pool. """ - return _SITE_POOLS[frappe.local.site]["read_only" if read_only else "default"] + return _SITE_POOLS[frappe.local.site]["read_only" if self.read_only else "default"] - def create_connection_pool(self, read_only=False): + def create_connection_pool(self): pool = mariadb.ConnectionPool( - pool_name=self.get_pool_name(read_only=read_only), + pool_name=self.get_pool_name(), pool_size=_MAX_POOL_SIZE, pool_reset_connection=False, ) pool.set_config(**self.get_connection_settings()) - if read_only: + if self.read_only: _SITE_POOLS[frappe.local.site].read_only = pool else: _SITE_POOLS[frappe.local.site].default = pool