refactor(db-read_only): Track conn type in Database instance

This commit is contained in:
Gavin D'souza 2022-06-23 19:40:17 +05:30
parent 574f160d3c
commit ef078a4ab5
4 changed files with 30 additions and 16 deletions

View file

@ -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

View file

@ -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):

View file

@ -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:

View file

@ -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