fix(servers): исправить сохранение и опрос серверов
This commit is contained in:
1 parent
88326d9851
commit
c30f817926
10 files changed
+635
-62
No files matched your search
@@ -0,0 +1,49 @@
|
||||
/** A synchronous lock: React state alone cannot prevent two calls in one tick. */
|
||||
export class OperationGate {
|
||||
private keys = new Set<string>()
|
||||
|
||||
acquire(key: string): boolean {
|
||||
if (this.keys.has(key)) return false
|
||||
this.keys.add(key)
|
||||
return true
|
||||
}
|
||||
|
||||
release(key: string) { this.keys.delete(key) }
|
||||
has(key: string) { return this.keys.has(key) }
|
||||
}
|
||||
|
||||
export type PollResult = { id: string; error: string | null }
|
||||
|
||||
export function serverOperationError(error: unknown): string {
|
||||
if (error && typeof error === "object" && "status" in error && error.status === 403) {
|
||||
return "Недостаточно прав для этого действия."
|
||||
}
|
||||
if (error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError")) {
|
||||
return "Время ожидания истекло. Результат операции неизвестен — обновите данные перед повтором."
|
||||
}
|
||||
if (error instanceof TypeError) return "Нет соединения с сервером. Проверьте подключение и обновите данные."
|
||||
return error instanceof Error ? error.message : "Не удалось выполнить действие. Попробуйте ещё раз."
|
||||
}
|
||||
|
||||
/** Bounded polling, preserving one outcome for every requested server. */
|
||||
export async function pollServers(
|
||||
ids: string[],
|
||||
poll: (id: string) => Promise<void>,
|
||||
): Promise<PollResult[]> {
|
||||
const uniqueIds = [...new Set(ids)]
|
||||
const results: PollResult[] = new Array(uniqueIds.length)
|
||||
let next = 0
|
||||
await Promise.all(Array.from({ length: Math.min(4, uniqueIds.length) }, async () => {
|
||||
while (next < uniqueIds.length) {
|
||||
const index = next++
|
||||
const id = uniqueIds[index]
|
||||
try {
|
||||
await poll(id)
|
||||
results[index] = { id, error: null }
|
||||
} catch (error) {
|
||||
results[index] = { id, error: serverOperationError(error) }
|
||||
}
|
||||
}
|
||||
}))
|
||||
return results
|
||||
}
|
||||
Reference in new issue
Block a user