Edgewall Software

Ticket #7392: 0001-db-add-the-ability-to-have-a-seperate-write-databas.patch

File 0001-db-add-the-ability-to-have-a-seperate-write-databas.patch, 4.6 KB (added by Axel Gembe, 6 months ago)

[PATCH 1/3] db: add the ability to have a seperate write database

  • trac/db/api.py

    From 1eed61a7374adc998f1bb6311abe644fc4dc1e9a Mon Sep 17 00:00:00 2001
    From: Axel Gembe <ago@bastart.eu.org>
    Date: Thu, 26 Jun 2008 09:42:05 +0200
    Subject: [PATCH 1/3] db: add the ability to have a seperate write database
    
    Basically this patch adds a second connection pool for the write server. The new
    configuration option is "database_write", with the same syntax as the normal
    "database" option. If database_write is omitted then the normal pool will be
    used.
    It works by returning a DatabasePair instead of the actual database connection.
    Much existing code will have to be changed to support this change, which will be
    done in the following patch. The goal of this is to implement easy
    synchronization between two Trac instances by having one master database which
    pushes changes to the slave databases.
    
    Signed-off-by: Axel Gembe <ago@bastart.eu.org>
    ---
     trac/db/api.py |   42 ++++++++++++++++++++++++++++++++++++------
     trac/env.py    |    2 +-
     2 files changed, 37 insertions(+), 7 deletions(-)
    
    diff --git a/trac/db/api.py b/trac/db/api.py
    index e194293..acbb9e7 100644
    a b  
    4949        """Return the DDL statements necessary to create the specified table, 
    5050        including indices.""" 
    5151 
     52class DatabasePair(object): 
     53    """ 
     54    Holds two database connections, one for reading and one for writing. 
     55    """ 
     56    def __init__(self, db, dbwr): 
     57        self.read = db 
     58        self.write = dbwr 
    5259 
    5360class DatabaseManager(Component): 
    5461 
     
    5966        [wiki:TracEnvironment#DatabaseConnectionStrings string] for this 
    6067        project""") 
    6168 
     69    write_connection_uri = Option('trac', 'database_write', '', 
     70        """Database write connection 
     71        [wiki:TracEnvironment#DatabaseConnectionStrings string] for this 
     72        project""") 
     73 
    6274    timeout = IntOption('trac', 'timeout', '20', 
    6375        """Timeout value for database connection, in seconds. 
    6476        Use '0' to specify ''no timeout''. ''(Since 0.11)''""") 
    6577 
    6678    def __init__(self): 
    6779        self._cnx_pool = None 
     80        self._cnx_pool_write = None 
    6881 
    6982    def init_db(self): 
    70         connector, args = self._get_connector() 
     83        connector, args = self._get_connector(self.connection_uri) 
     84        if self.write_connection_uri and self.write_connection_uri != '': 
     85            connector, args = self._get_connector(self.write_connection_uri) 
    7186        connector.init_db(**args) 
    7287 
    73     def get_connection(self): 
     88    def _create_pool(self): 
    7489        if not self._cnx_pool: 
    75             connector, args = self._get_connector() 
     90            connector, args = self._get_connector(self.connection_uri) 
    7691            self._cnx_pool = ConnectionPool(5, connector, **args) 
    77         return self._cnx_pool.get_cnx(self.timeout or None) 
     92        if self.write_connection_uri and self.write_connection_uri != '' and not self._cnx_pool_write: 
     93            connector, args = self._get_connector(self.write_connection_uri) 
     94            ### FIXME: Connection pool does not handle the max number although it might be needed 
     95            self._cnx_pool_write = ConnectionPool(1, connector, **args) 
     96 
     97    def get_connection(self): 
     98        self._create_pool() 
     99        conn = self._cnx_pool.get_cnx(self.timeout or None) 
     100        if not self.write_connection_uri or self.write_connection_uri == '': 
     101            return DatabasePair(conn, conn); 
     102        else: 
     103            return DatabasePair(conn, self._cnx_pool_write.get_cnx(self.timeout or None)) 
    78104 
    79105    def shutdown(self, tid=None): 
    80106        if self._cnx_pool: 
    81107            self._cnx_pool.shutdown(tid) 
    82108            if not tid: 
    83109                self._cnx_pool = None 
     110        if self._cnx_pool_write: 
     111            self._cnx_pool_write.shutdown(tid) 
     112            if not tid: 
     113                self._cnx_pool_write = None 
    84114 
    85     def _get_connector(self): ### FIXME: Make it public? 
    86         scheme, args = _parse_db_str(self.connection_uri) 
     115    def _get_connector(self, db_str): ### FIXME: Make it public? 
     116        scheme, args = _parse_db_str(db_str) 
    87117        candidates = {} 
    88118        for connector in self.connectors: 
    89119            for scheme_, priority in connector.get_supported_schemes(): 
  • trac/env.py

    diff --git a/trac/env.py b/trac/env.py
    index d082269..11a4314 100644
    a b  
    253253            fd.close() 
    254254 
    255255    def get_db_cnx(self): 
    256         """Return a database connection from the connection pool.""" 
     256        """Return a database connection pair from the connection pool.""" 
    257257        return DatabaseManager(self).get_connection() 
    258258 
    259259    def shutdown(self, tid=None):