Skip to content

Commit e3af829

Browse files
authored
refactor: optimize database server address tracing with WeakMap (#1027)
This change improves the database server address tracing mechanism by: - Using WeakMap to cache server address and port information from DSN at PDO creation time - Extracting server information directly from DSN in createPdoConnection - Removing complex fallback logic from EventHandleListener that relied on config and read/write PDO detection - Simplifying server address/port retrieval to direct Context lookups The new approach is more efficient and reliable, capturing the actual connection details at the earliest point rather than inferring them later. Co-authored-by: Deeka Wong <[email protected]>
1 parent 6e659b9 commit e3af829

File tree

2 files changed

+25
-26
lines changed

2 files changed

+25
-26
lines changed

src/Tracing/Aspect/DbConnectionAspect.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,46 @@
1515
use Hyperf\Context\Context;
1616
use Hyperf\Di\Aop\AbstractAspect;
1717
use Hyperf\Di\Aop\ProceedingJoinPoint;
18-
use PDO;
18+
use WeakMap;
1919

2020
use function Hyperf\Tappable\tap;
2121

2222
class DbConnectionAspect extends AbstractAspect
2323
{
2424
public array $classes = [
25+
'Hyperf\Database\Connectors\Connector::createPdoConnection',
2526
'Hyperf\Database\Connection::getPdoForSelect',
2627
'Hyperf\Database\Connection::getPdo',
2728
];
2829

30+
private WeakMap $serverCache;
31+
32+
public function __construct()
33+
{
34+
$this->serverCache = new WeakMap();
35+
}
36+
2937
public function process(ProceedingJoinPoint $proceedingJoinPoint)
3038
{
3139
return tap($proceedingJoinPoint->process(), function ($pdo) use ($proceedingJoinPoint) {
32-
if ($proceedingJoinPoint->methodName === 'getPdoForSelect') {
33-
$arguments = $proceedingJoinPoint->arguments['keys'] ?? [];
34-
Context::set(Constants::TRACE_DB_USE_READ_PDO, $arguments['useReadPdo'] ?? false);
40+
if ($proceedingJoinPoint->methodName === 'createPdoConnection') {
41+
$dsn = $proceedingJoinPoint->arguments['keys']['dsn'] ?? '';
42+
$pattern = '/host=([^;]+);port=(\d+);?/';
43+
if (preg_match($pattern, $dsn, $matches)) {
44+
$host = $matches[1];
45+
$port = $matches[2];
46+
$this->serverCache[$pdo] = ['host' => $host, 'port' => $port];
47+
}
48+
return;
3549
}
3650

3751
Context::getOrSet(self::class, function () use ($pdo) {
38-
$connectionStatus = $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS);
39-
[$host] = explode(' ', $connectionStatus);
52+
$server = $this->serverCache[$pdo] ?? null;
4053

41-
Context::set(Constants::TRACE_DB_SERVER_ADDRESS, $host);
54+
if (is_array($server)) {
55+
Context::set(Constants::TRACE_DB_SERVER_ADDRESS, $server['host']);
56+
Context::set(Constants::TRACE_DB_SERVER_PORT, $server['port']);
57+
}
4258

4359
return true;
4460
});

src/Tracing/Listener/EventHandleListener.php

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -186,32 +186,15 @@ protected function handleDbQueryExecuted(DbEvent\QueryExecuted $event): void
186186
$data['db.collection.name'] = $sqlParse['table'];
187187
}
188188

189-
// Get port from config
190-
$host = (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost');
191-
if (! Context::has(Constants::TRACE_DB_SERVER_PORT)) {
192-
$useReadPdo = (bool) Context::get(Constants::TRACE_DB_USE_READ_PDO, false);
193-
$dbConfig = (fn () => $this->config ?? ['host' => $host, 'port' => 3306])->call($event->connection);
194-
$hosts = $dbConfig['write']['host'] ?? [$dbConfig['host']];
195-
$ports = $dbConfig['write']['port'] ?? [$dbConfig['port']];
196-
if ($useReadPdo) {
197-
$hosts = $dbConfig['read']['host'] ?? $hosts;
198-
$ports = $dbConfig['read']['port'] ?? $ports;
199-
}
200-
$index = array_search($host, $hosts, true);
201-
$port = $ports[$index] ?? $ports[0] ?? 3306;
202-
} else {
203-
$port = (int) Context::get(Constants::TRACE_DB_SERVER_PORT);
204-
}
205-
206189
$pool = $this->container->get(PoolFactory::class)->getPool($event->connectionName);
207190
$data += [
208191
'db.pool.name' => $event->connectionName,
209192
'db.pool.max' => $pool->getOption()->getMaxConnections(),
210193
'db.pool.max_idle_time' => $pool->getOption()->getMaxIdleTime(),
211194
'db.pool.idle' => $pool->getConnectionsInChannel(),
212195
'db.pool.using' => $pool->getCurrentConnections(),
213-
'server.address' => $host,
214-
'server.port' => $port,
196+
'server.address' => (string) Context::get(Constants::TRACE_DB_SERVER_ADDRESS, 'localhost'),
197+
'server.port' => (int) Context::get(Constants::TRACE_DB_SERVER_PORT, 3306),
215198
];
216199

217200
if ($this->feature->isTracingTagEnabled('db.sql.bindings', true)) {

0 commit comments

Comments
 (0)