154 lines
4.0 KiB
TypeScript
154 lines
4.0 KiB
TypeScript
// =====================================================
|
|
// 智能 IP 連線池
|
|
// =====================================================
|
|
|
|
import { db } from './database';
|
|
import { ipConnectionManager } from './ip-based-connection-manager';
|
|
|
|
export class SmartIPConnectionPool {
|
|
private static instance: SmartIPConnectionPool;
|
|
private connectionCounter = 0;
|
|
|
|
private constructor() {}
|
|
|
|
public static getInstance(): SmartIPConnectionPool {
|
|
if (!SmartIPConnectionPool.instance) {
|
|
SmartIPConnectionPool.instance = new SmartIPConnectionPool();
|
|
}
|
|
return SmartIPConnectionPool.instance;
|
|
}
|
|
|
|
// 設置客戶端 IP
|
|
public setClientIP(ip: string) {
|
|
ipConnectionManager.setClientIP(ip);
|
|
}
|
|
|
|
// 獲取智能連線(帶 IP 追蹤)
|
|
public async getSmartConnection(metadata?: {
|
|
userAgent?: string;
|
|
requestId?: string;
|
|
clientIP?: string;
|
|
}): Promise<{
|
|
connection: any;
|
|
connectionId: string;
|
|
release: () => void;
|
|
}> {
|
|
const connectionId = `conn_${++this.connectionCounter}_${Date.now()}`;
|
|
|
|
// 設置客戶端 IP
|
|
if (metadata?.clientIP) {
|
|
ipConnectionManager.setClientIP(metadata.clientIP);
|
|
}
|
|
|
|
try {
|
|
// 獲取實際連線
|
|
const connection = await db.getConnection();
|
|
|
|
// 註冊到 IP 連線管理器
|
|
ipConnectionManager.registerConnection(connectionId, {
|
|
userAgent: metadata?.userAgent,
|
|
requestId: metadata?.requestId
|
|
});
|
|
|
|
// 創建包裝的釋放函數
|
|
const release = () => {
|
|
ipConnectionManager.releaseConnection(connectionId);
|
|
};
|
|
|
|
console.log(`🔗 獲取智能 IP 連線: ${connectionId}`);
|
|
|
|
return {
|
|
connection,
|
|
connectionId,
|
|
release
|
|
};
|
|
} catch (error) {
|
|
console.error(`❌ 獲取智能 IP 連線失敗: ${connectionId}`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// 執行智能查詢(帶 IP 追蹤)
|
|
public async executeQuery<T = any>(
|
|
sql: string,
|
|
params?: any[],
|
|
metadata?: {
|
|
userAgent?: string;
|
|
requestId?: string;
|
|
clientIP?: string;
|
|
}
|
|
): Promise<T[]> {
|
|
const { connection, connectionId, release } = await this.getSmartConnection(metadata);
|
|
|
|
try {
|
|
// 更新連線使用時間
|
|
ipConnectionManager.updateConnectionUsage(connectionId);
|
|
|
|
// 執行查詢
|
|
const [rows] = await connection.execute(sql, params);
|
|
return rows as T[];
|
|
} catch (error) {
|
|
console.error(`❌ 智能 IP 查詢失敗: ${connectionId}`, error);
|
|
throw error;
|
|
} finally {
|
|
// 確保釋放連線
|
|
release();
|
|
}
|
|
}
|
|
|
|
// 執行智能單一查詢
|
|
public async executeQueryOne<T = any>(
|
|
sql: string,
|
|
params?: any[],
|
|
metadata?: {
|
|
userAgent?: string;
|
|
requestId?: string;
|
|
clientIP?: string;
|
|
}
|
|
): Promise<T | null> {
|
|
const results = await this.executeQuery<T>(sql, params, metadata);
|
|
return results.length > 0 ? results[0] : null;
|
|
}
|
|
|
|
// 清理當前 IP 的所有連線
|
|
public async cleanupCurrentIPConnections(): Promise<{
|
|
success: boolean;
|
|
killedCount: number;
|
|
message: string;
|
|
}> {
|
|
return await ipConnectionManager.cleanupConnectionsByIP();
|
|
}
|
|
|
|
// 清理指定 IP 的所有連線
|
|
public async cleanupIPConnections(targetIP: string): Promise<{
|
|
success: boolean;
|
|
killedCount: number;
|
|
message: string;
|
|
}> {
|
|
return await ipConnectionManager.cleanupConnectionsByIP(targetIP);
|
|
}
|
|
|
|
// 獲取當前 IP 的連線狀態
|
|
public async getCurrentIPConnections() {
|
|
return await ipConnectionManager.getConnectionsByIP();
|
|
}
|
|
|
|
// 獲取指定 IP 的連線狀態
|
|
public async getIPConnections(targetIP: string) {
|
|
return await ipConnectionManager.getConnectionsByIP(targetIP);
|
|
}
|
|
|
|
// 獲取本地連線統計
|
|
public getLocalConnectionStats() {
|
|
return ipConnectionManager.getLocalConnectionStats();
|
|
}
|
|
|
|
// 清理本地追蹤的連線
|
|
public cleanupLocalConnections() {
|
|
return ipConnectionManager.cleanupLocalConnections();
|
|
}
|
|
}
|
|
|
|
// 導出單例實例
|
|
export const smartIPPool = SmartIPConnectionPool.getInstance();
|