(self)
| 134 | await self._get_conn() |
| 135 | |
| 136 | async def _get_conn(self) -> mysql_connector.MySQLConnectionAbstract: |
| 137 | if self._conn: |
| 138 | try: # reuse if conn is still valid |
| 139 | if await self._conn.get_database() == self.database: |
| 140 | return self._conn |
| 141 | else: |
| 142 | self.logger.info("Cannot reuse MySQL connection, reconnecting...") |
| 143 | except: |
| 144 | self.logger.warning("MySQL connection check failed, reconnecting...", exc_info=True) |
| 145 | try: |
| 146 | await self._conn.close() |
| 147 | except: |
| 148 | pass |
| 149 | self._conn = None |
| 150 | |
| 151 | max_tries = 5 |
| 152 | for attempt in range(max_tries): |
| 153 | try: |
| 154 | self.logger.info(f"Connecting to MySQL at {self.container_ip} (Attempt {attempt + 1}/{max_tries})...") |
| 155 | self._conn = await mysql_connector.connect( |
| 156 | host=self.container_ip, |
| 157 | user='root', |
| 158 | password=self.password, |
| 159 | database=self.database, |
| 160 | connection_timeout=10, |
| 161 | read_timeout=30, |
| 162 | write_timeout=30 |
| 163 | ) |
| 164 | return self._conn |
| 165 | except Exception as e: |
| 166 | self.logger.error(f"MySQL connection error: {e}") |
| 167 | if attempt < max_tries - 1: |
| 168 | await asyncio.sleep(1) |
| 169 | |
| 170 | raise ConnectionError("Failed to connect to MySQL after multiple attempts.") |
| 171 | |
| 172 | |
| 173 | class SQLiteDatabase(Database): |
no outgoing calls
no test coverage detected