mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-26 23:56:02 +08:00
87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import { useState, useCallback } from "react";
|
|
import { toast } from "sonner";
|
|
import { useTranslation } from "react-i18next";
|
|
import {
|
|
streamCheckProvider,
|
|
type StreamCheckResult,
|
|
} from "@/lib/api/model-test";
|
|
import type { AppId } from "@/lib/api";
|
|
import { useResetCircuitBreaker } from "@/lib/query/failover";
|
|
|
|
export function useStreamCheck(appId: AppId) {
|
|
const { t } = useTranslation();
|
|
const [checkingIds, setCheckingIds] = useState<Set<string>>(new Set());
|
|
const resetCircuitBreaker = useResetCircuitBreaker();
|
|
|
|
const checkProvider = useCallback(
|
|
async (
|
|
providerId: string,
|
|
providerName: string,
|
|
): Promise<StreamCheckResult | null> => {
|
|
setCheckingIds((prev) => new Set(prev).add(providerId));
|
|
|
|
try {
|
|
const result = await streamCheckProvider(appId, providerId);
|
|
|
|
if (result.status === "operational") {
|
|
toast.success(
|
|
t("streamCheck.operational", {
|
|
providerName: providerName,
|
|
responseTimeMs: result.responseTimeMs,
|
|
defaultValue: `${providerName} 运行正常 (${result.responseTimeMs}ms)`,
|
|
}),
|
|
{ closeButton: true },
|
|
);
|
|
|
|
// 测试通过后重置熔断器状态
|
|
resetCircuitBreaker.mutate({ providerId, appType: appId });
|
|
} else if (result.status === "degraded") {
|
|
toast.warning(
|
|
t("streamCheck.degraded", {
|
|
providerName: providerName,
|
|
responseTimeMs: result.responseTimeMs,
|
|
defaultValue: `${providerName} 响应较慢 (${result.responseTimeMs}ms)`,
|
|
}),
|
|
);
|
|
|
|
// 降级状态也重置熔断器,因为至少能通信
|
|
resetCircuitBreaker.mutate({ providerId, appType: appId });
|
|
} else {
|
|
toast.error(
|
|
t("streamCheck.failed", {
|
|
providerName: providerName,
|
|
message: result.message,
|
|
defaultValue: `${providerName} 检查失败: ${result.message}`,
|
|
}),
|
|
);
|
|
}
|
|
|
|
return result;
|
|
} catch (e) {
|
|
toast.error(
|
|
t("streamCheck.error", {
|
|
providerName: providerName,
|
|
error: String(e),
|
|
defaultValue: `${providerName} 检查出错: ${String(e)}`,
|
|
}),
|
|
);
|
|
return null;
|
|
} finally {
|
|
setCheckingIds((prev) => {
|
|
const next = new Set(prev);
|
|
next.delete(providerId);
|
|
return next;
|
|
});
|
|
}
|
|
},
|
|
[appId, t, resetCircuitBreaker],
|
|
);
|
|
|
|
const isChecking = useCallback(
|
|
(providerId: string) => checkingIds.has(providerId),
|
|
[checkingIds],
|
|
);
|
|
|
|
return { checkProvider, isChecking };
|
|
}
|