1
0
mirror of https://github.com/ZeroCatDev/Classworks.git synced 2026-02-04 07:53:11 +00:00
Classworks/src/utils/serverRotation.js
copilot-swe-agent[bot] b084c80b18 Address code review feedback: optimize callbacks and clarify Socket.IO limitation
Co-authored-by: Sunwuyuan <88357633+Sunwuyuan@users.noreply.github.com>
2026-01-19 11:57:14 +00:00

105 lines
3.3 KiB
JavaScript

/**
* Server rotation utility for Classworks Cloud provider
* Provides fallback mechanism across multiple server endpoints
*/
import { getSetting } from "./settings";
// Server list for classworkscloud provider (in priority order)
const CLASSWORKS_CLOUD_SERVERS = [
"https://kv-service.houlang.cloud",
"https://kv-service.wuyuan.dev",
];
/**
* Get the list of servers to try for the given provider
* @param {string} provider - The provider type
* @returns {string[]} Array of server URLs to try
*/
export function getServerList(provider) {
if (provider === "classworkscloud") {
return [...CLASSWORKS_CLOUD_SERVERS];
}
// For other providers, use the configured domain
const domain = getSetting("server.domain");
return domain ? [domain] : [];
}
/**
* Try an operation with server rotation fallback
* @param {Function} operation - Async function that takes a serverUrl and returns a promise
* @param {Object} options - Options
* @param {string} options.provider - Provider type (optional, defaults to current setting)
* @param {Function} options.onServerTried - Callback called when a server is tried (optional)
* @returns {Promise} Result from the first successful server, or throws the last error
*/
export async function tryWithRotation(operation, options = {}) {
const provider = options.provider || getSetting("server.provider");
const onServerTried = options.onServerTried;
const hasCallback = typeof onServerTried === 'function';
const servers = getServerList(provider);
const triedServers = [];
let lastError = null;
for (const serverUrl of servers) {
try {
triedServers.push({ url: serverUrl, status: "trying" });
if (hasCallback) {
onServerTried({ url: serverUrl, status: "trying", tried: [...triedServers] });
}
const result = await operation(serverUrl);
triedServers[triedServers.length - 1].status = "success";
if (hasCallback) {
onServerTried({ url: serverUrl, status: "success", tried: [...triedServers] });
}
return result;
} catch (error) {
lastError = error;
triedServers[triedServers.length - 1].status = "failed";
triedServers[triedServers.length - 1].error = error.message || String(error);
if (hasCallback) {
onServerTried({ url: serverUrl, status: "failed", error, tried: [...triedServers] });
}
// Continue to next server
console.warn(`Server ${serverUrl} failed:`, error.message);
}
}
// All servers failed
console.error("All servers failed. Tried:", triedServers);
const error = lastError || new Error("All servers failed");
error.triedServers = triedServers;
throw error;
}
/**
* Get the effective server URL for the current provider
* For classworkscloud, returns the first server in the list
* For other providers, returns the configured domain
* @returns {string} Server URL
*/
export function getEffectiveServerUrl() {
const provider = getSetting("server.provider");
if (provider === "classworkscloud") {
return CLASSWORKS_CLOUD_SERVERS[0];
}
return getSetting("server.domain") || "";
}
/**
* Check if rotation is enabled for the current provider
* @returns {boolean}
*/
export function isRotationEnabled() {
const provider = getSetting("server.provider");
return provider === "classworkscloud";
}