修復 too many connection 問題
This commit is contained in:
37
app/api/competitions/[id]/route.ts
Normal file
37
app/api/competitions/[id]/route.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// =====================================================
|
||||
// 獲取競賽詳情 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { CompetitionService } from '@/lib/services/database-service';
|
||||
|
||||
export async function GET(request: NextRequest, { params }: { params: { id: string } }) {
|
||||
try {
|
||||
const { id } = await params;
|
||||
|
||||
// 獲取競賽詳情
|
||||
const competition = await CompetitionService.getCompetitionById(id);
|
||||
|
||||
if (!competition) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '競賽不存在',
|
||||
error: '找不到指定的競賽'
|
||||
}, { status: 404 });
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '競賽詳情獲取成功',
|
||||
data: competition
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('獲取競賽詳情失敗:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
message: '獲取競賽詳情失敗',
|
||||
error: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
122
app/api/connection-monitor/route.ts
Normal file
122
app/api/connection-monitor/route.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
// =====================================================
|
||||
// 連線監控 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { smartPool } from '@/lib/smart-connection-pool';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const action = searchParams.get('action') || 'stats';
|
||||
|
||||
switch (action) {
|
||||
case 'stats':
|
||||
// 獲取連線統計
|
||||
const stats = smartPool.getConnectionStats();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線統計獲取成功',
|
||||
data: stats
|
||||
});
|
||||
|
||||
case 'cleanup':
|
||||
// 強制清理連線
|
||||
console.log('🧹 執行強制連線清理...');
|
||||
smartPool.forceCleanup();
|
||||
const newStats = smartPool.getConnectionStats();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線清理完成',
|
||||
data: newStats
|
||||
});
|
||||
|
||||
case 'test':
|
||||
// 測試智能連線
|
||||
try {
|
||||
const testResult = await smartPool.executeQueryOne(
|
||||
'SELECT 1 as test_value',
|
||||
[],
|
||||
{ userId: 'test', sessionId: 'test-session', requestId: 'test-request' }
|
||||
);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '智能連線測試成功',
|
||||
data: {
|
||||
testResult,
|
||||
stats: smartPool.getConnectionStats()
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '智能連線測試失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['stats', 'cleanup', 'test']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 連線監控 API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'API 請求失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { action, maxIdleTime, maxConnectionAge } = body;
|
||||
|
||||
switch (action) {
|
||||
case 'config':
|
||||
// 更新清理配置
|
||||
smartPool.setCleanupParams(maxIdleTime, maxConnectionAge);
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '清理配置更新成功',
|
||||
data: {
|
||||
maxIdleTime: maxIdleTime || '未變更',
|
||||
maxConnectionAge: maxConnectionAge || '未變更'
|
||||
}
|
||||
});
|
||||
|
||||
case 'cleanup':
|
||||
// 強制清理連線
|
||||
console.log('🧹 執行強制連線清理...');
|
||||
smartPool.forceCleanup();
|
||||
const stats = smartPool.getConnectionStats();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線清理完成',
|
||||
data: stats
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['config', 'cleanup']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 連線監控 POST API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'API 請求失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
59
app/api/debug-ip/route.ts
Normal file
59
app/api/debug-ip/route.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
// =====================================================
|
||||
// IP 調試 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { smartIPDetector } from '@/lib/smart-ip-detector';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
// 使用智能 IP 偵測器
|
||||
const ipDetection = smartIPDetector.detectClientIP(request);
|
||||
|
||||
// 收集所有可能的 IP 信息
|
||||
const ipInfo = {
|
||||
// 智能偵測結果
|
||||
smartDetection: ipDetection,
|
||||
// 請求標頭
|
||||
headers: {
|
||||
'x-forwarded-for': request.headers.get('x-forwarded-for'),
|
||||
'x-real-ip': request.headers.get('x-real-ip'),
|
||||
'cf-connecting-ip': request.headers.get('cf-connecting-ip'),
|
||||
'x-client-ip': request.headers.get('x-client-ip'),
|
||||
'x-forwarded': request.headers.get('x-forwarded'),
|
||||
'x-cluster-client-ip': request.headers.get('x-cluster-client-ip'),
|
||||
'x-original-forwarded-for': request.headers.get('x-original-forwarded-for'),
|
||||
'x-remote-addr': request.headers.get('x-remote-addr'),
|
||||
'remote-addr': request.headers.get('remote-addr'),
|
||||
'client-ip': request.headers.get('client-ip'),
|
||||
'user-agent': request.headers.get('user-agent'),
|
||||
'host': request.headers.get('host'),
|
||||
},
|
||||
// NextRequest 的 IP
|
||||
nextRequestIP: request.ip,
|
||||
// 環境變數
|
||||
env: {
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
VERCEL: process.env.VERCEL,
|
||||
VERCEL_REGION: process.env.VERCEL_REGION,
|
||||
},
|
||||
// 所有標頭(用於調試)
|
||||
allHeaders: Object.fromEntries(request.headers.entries()),
|
||||
};
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: 'IP 調試信息獲取成功',
|
||||
data: ipInfo,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ IP 調試 API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'IP 調試失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
104
app/api/emergency-cleanup/route.ts
Normal file
104
app/api/emergency-cleanup/route.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
// =====================================================
|
||||
// 緊急連線清理 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { emergencyCleanup } from '@/lib/emergency-connection-cleanup';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { action } = body;
|
||||
|
||||
switch (action) {
|
||||
case 'cleanup':
|
||||
// 執行緊急清理
|
||||
console.log('🚨 收到緊急清理請求');
|
||||
await emergencyCleanup.emergencyCleanup();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '緊急清理完成',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'kill-all':
|
||||
// 強制殺死所有連線
|
||||
console.log('💀 收到強制殺死連線請求');
|
||||
await emergencyCleanup.forceKillAllConnections();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '強制殺死連線完成',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'details':
|
||||
// 獲取連線詳情
|
||||
const connections = await emergencyCleanup.getConnectionDetails();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線詳情獲取成功',
|
||||
data: {
|
||||
connectionCount: connections.length,
|
||||
connections: connections
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['cleanup', 'kill-all', 'details']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 緊急清理 API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '緊急清理失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const action = searchParams.get('action') || 'details';
|
||||
|
||||
switch (action) {
|
||||
case 'details':
|
||||
// 獲取連線詳情
|
||||
const connections = await emergencyCleanup.getConnectionDetails();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線詳情獲取成功',
|
||||
data: {
|
||||
connectionCount: connections.length,
|
||||
connections: connections
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['details']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 緊急清理 GET API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '獲取連線詳情失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
177
app/api/ip-cleanup/route.ts
Normal file
177
app/api/ip-cleanup/route.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
// =====================================================
|
||||
// 基於 IP 的連線清理 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { smartIPPool } from '@/lib/smart-ip-connection-pool';
|
||||
import { smartIPDetector } from '@/lib/smart-ip-detector';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { action, targetIP } = body;
|
||||
// 使用智能 IP 偵測器
|
||||
const ipDetection = smartIPDetector.detectClientIP(request);
|
||||
const clientIP = ipDetection.detectedIP;
|
||||
|
||||
console.log('🎯 智能 IP 偵測結果:', {
|
||||
detectedIP: clientIP,
|
||||
confidence: ipDetection.confidence,
|
||||
source: ipDetection.source,
|
||||
isPublicIP: ipDetection.isPublicIP,
|
||||
allCandidates: ipDetection.allCandidates
|
||||
});
|
||||
|
||||
// 設置客戶端 IP
|
||||
smartIPPool.setClientIP(clientIP);
|
||||
|
||||
switch (action) {
|
||||
case 'cleanup-current':
|
||||
// 清理當前 IP 的連線
|
||||
console.log(`🧹 收到清理當前 IP 連線請求: ${clientIP}`);
|
||||
const cleanupResult = await smartIPPool.cleanupCurrentIPConnections();
|
||||
|
||||
return NextResponse.json({
|
||||
success: cleanupResult.success,
|
||||
message: cleanupResult.message,
|
||||
data: {
|
||||
clientIP,
|
||||
killedCount: cleanupResult.killedCount
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'cleanup-specific':
|
||||
// 清理指定 IP 的連線
|
||||
if (!targetIP) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '缺少目標 IP 參數'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
console.log(`🧹 收到清理指定 IP 連線請求: ${targetIP}`);
|
||||
const specificCleanupResult = await smartIPPool.cleanupIPConnections(targetIP);
|
||||
|
||||
return NextResponse.json({
|
||||
success: specificCleanupResult.success,
|
||||
message: specificCleanupResult.message,
|
||||
data: {
|
||||
targetIP,
|
||||
killedCount: specificCleanupResult.killedCount
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'cleanup-local':
|
||||
// 清理本地追蹤的連線
|
||||
console.log('🧹 收到清理本地連線請求');
|
||||
const localCleanupCount = smartIPPool.cleanupLocalConnections();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `已清理 ${localCleanupCount} 個本地追蹤的連線`,
|
||||
data: {
|
||||
clientIP,
|
||||
cleanedCount: localCleanupCount
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['cleanup-current', 'cleanup-specific', 'cleanup-local']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ IP 清理 API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: 'IP 清理失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const action = searchParams.get('action') || 'status';
|
||||
const targetIP = searchParams.get('ip');
|
||||
// 使用智能 IP 偵測器
|
||||
const ipDetection = smartIPDetector.detectClientIP(request);
|
||||
const clientIP = ipDetection.detectedIP;
|
||||
|
||||
// 設置客戶端 IP
|
||||
smartIPPool.setClientIP(clientIP);
|
||||
|
||||
switch (action) {
|
||||
case 'status':
|
||||
// 獲取當前 IP 的連線狀態
|
||||
const currentIPStatus = await smartIPPool.getCurrentIPConnections();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線狀態獲取成功',
|
||||
data: {
|
||||
detectedIP: clientIP,
|
||||
...currentIPStatus
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'status-specific':
|
||||
// 獲取指定 IP 的連線狀態
|
||||
if (!targetIP) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '缺少目標 IP 參數'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
const specificIPStatus = await smartIPPool.getIPConnections(targetIP);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '指定 IP 連線狀態獲取成功',
|
||||
data: {
|
||||
targetIP,
|
||||
...specificIPStatus
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'local-stats':
|
||||
// 獲取本地連線統計
|
||||
const localStats = smartIPPool.getLocalConnectionStats();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '本地連線統計獲取成功',
|
||||
data: {
|
||||
detectedIP: clientIP,
|
||||
...localStats
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['status', 'status-specific', 'local-stats']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ IP 清理 GET API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '獲取連線狀態失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
78
app/api/set-client-ip/route.ts
Normal file
78
app/api/set-client-ip/route.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
// =====================================================
|
||||
// 手動設置客戶端 IP API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { smartIPPool } from '@/lib/smart-ip-connection-pool';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { clientIP } = body;
|
||||
|
||||
if (!clientIP) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '缺少客戶端 IP 參數'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
console.log('🔧 手動設置客戶端 IP:', clientIP);
|
||||
|
||||
// 設置客戶端 IP
|
||||
smartIPPool.setClientIP(clientIP);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `客戶端 IP 已設置為: ${clientIP}`,
|
||||
data: {
|
||||
clientIP,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 設置客戶端 IP 失敗:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '設置客戶端 IP 失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const clientIP = searchParams.get('ip');
|
||||
|
||||
if (!clientIP) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '缺少 IP 參數'
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
console.log('🔧 通過 GET 設置客戶端 IP:', clientIP);
|
||||
|
||||
// 設置客戶端 IP
|
||||
smartIPPool.setClientIP(clientIP);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `客戶端 IP 已設置為: ${clientIP}`,
|
||||
data: {
|
||||
clientIP,
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 設置客戶端 IP 失敗:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '設置客戶端 IP 失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
100
app/api/test-shutdown/route.ts
Normal file
100
app/api/test-shutdown/route.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
// =====================================================
|
||||
// 測試資料庫關閉機制 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { dbShutdownManager } from '@/lib/database-shutdown-manager';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const action = searchParams.get('action') || 'status';
|
||||
|
||||
switch (action) {
|
||||
case 'status':
|
||||
// 獲取關閉狀態
|
||||
const status = dbShutdownManager.getShutdownStatus();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '關閉狀態查詢成功',
|
||||
data: status
|
||||
});
|
||||
|
||||
case 'test':
|
||||
// 測試關閉機制(不會真的關閉)
|
||||
console.log('🧪 測試關閉機制...');
|
||||
const testStatus = dbShutdownManager.getShutdownStatus();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '關閉機制測試成功',
|
||||
data: {
|
||||
...testStatus,
|
||||
testTime: new Date().toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
case 'force':
|
||||
// 強制關閉(僅用於測試)
|
||||
console.log('🚨 執行強制關閉測試...');
|
||||
dbShutdownManager.forceShutdown();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '強制關閉測試完成',
|
||||
data: {
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['status', 'test', 'force']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 測試關閉機制時發生錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '測試失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { action } = body;
|
||||
|
||||
switch (action) {
|
||||
case 'graceful':
|
||||
// 優雅關閉(僅用於測試)
|
||||
console.log('🔄 執行優雅關閉測試...');
|
||||
await dbShutdownManager.gracefulShutdown();
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '優雅關閉測試完成',
|
||||
data: {
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['graceful']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 執行關閉測試時發生錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '關閉測試失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
96
app/api/ultimate-kill/route.ts
Normal file
96
app/api/ultimate-kill/route.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
// =====================================================
|
||||
// 終極連線清理 API
|
||||
// =====================================================
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { ultimateKiller } from '@/lib/ultimate-connection-killer';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { action } = body;
|
||||
|
||||
switch (action) {
|
||||
case 'kill-all':
|
||||
// 終極清理 - 殺死所有連線
|
||||
console.log('💀 收到終極清理請求');
|
||||
const killResult = await ultimateKiller.ultimateKill();
|
||||
|
||||
return NextResponse.json({
|
||||
success: killResult.success,
|
||||
message: killResult.message || '終極清理完成',
|
||||
data: killResult,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
case 'restart':
|
||||
// 強制重啟資料庫連線
|
||||
console.log('🔄 收到強制重啟請求');
|
||||
const restartResult = await ultimateKiller.forceRestart();
|
||||
|
||||
return NextResponse.json({
|
||||
success: restartResult.success,
|
||||
message: restartResult.message || '強制重啟完成',
|
||||
data: restartResult,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['kill-all', 'restart']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 終極清理 API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '終極清理失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const action = searchParams.get('action') || 'status';
|
||||
|
||||
switch (action) {
|
||||
case 'status':
|
||||
// 檢查連線狀態
|
||||
const status = await ultimateKiller.checkStatus();
|
||||
|
||||
if (status) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: '連線狀態獲取成功',
|
||||
data: status,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} else {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無法獲取連線狀態'
|
||||
}, { status: 500 });
|
||||
}
|
||||
|
||||
default:
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '無效的操作參數',
|
||||
availableActions: ['status']
|
||||
}, { status: 400 });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ 終極清理 GET API 錯誤:', error);
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '獲取連線狀態失敗',
|
||||
details: error instanceof Error ? error.message : '未知錯誤'
|
||||
}, { status: 500 });
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user