feat: optimize delay checker concurrency strategy

This commit is contained in:
GyDi 2022-04-10 02:58:48 +08:00
parent 68ad5e2320
commit 3001c780bd
No known key found for this signature in database
GPG Key ID: 1C95E0D3467B3084
4 changed files with 34 additions and 38 deletions

View File

@ -70,12 +70,9 @@ const ProxyGlobal = (props: Props) => {
const onCheckAll = useLockFn(async () => { const onCheckAll = useLockFn(async () => {
const names = sortedProxies.map((p) => p.name); const names = sortedProxies.map((p) => p.name);
await delayManager.checkListDelay( await delayManager.checkListDelay({ names, groupName, skipNum: 8 }, () =>
{ names, groupName, skipNum: 8, maxTimeout: 600 }, mutate("getProxies")
() => mutate("getProxies")
); );
mutate("getProxies");
}); });
useEffect(() => onLocation(false), [groupName]); useEffect(() => onLocation(false), [groupName]);

View File

@ -92,12 +92,11 @@ const ProxyGroup = ({ group }: Props) => {
const names = sortedProxies.map((p) => p.name); const names = sortedProxies.map((p) => p.name);
const groupName = group.name; const groupName = group.name;
await delayManager.checkListDelay( await delayManager.checkListDelay({ names, groupName, skipNum: 8 }, () =>
{ names, groupName, skipNum: 8, maxTimeout: 600 }, mutate("getProxies")
() => mutate("getProxies")
); );
mutate("getProxies"); console.log("finish");
}); });
// auto scroll to current index // auto scroll to current index

View File

@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react"; import { useEffect, useState } from "react";
import { useLockFn } from "ahooks";
import { CheckCircleOutlineRounded } from "@mui/icons-material"; import { CheckCircleOutlineRounded } from "@mui/icons-material";
import { import {
alpha, alpha,
@ -50,20 +51,15 @@ const ProxyItem = (props: Props) => {
} }
}, [proxy]); }, [proxy]);
const delayRef = useRef(false); const onDelay = useLockFn(async (e: any) => {
const onDelay = (e: any) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (delayRef.current) return; return delayManager
delayRef.current = true;
delayManager
.checkDelay(proxy.name, groupName) .checkDelay(proxy.name, groupName)
.then((result) => setDelay(result)) .then((result) => setDelay(result))
.catch(() => setDelay(1e6)) .catch(() => setDelay(1e6));
.finally(() => (delayRef.current = false)); });
};
return ( return (
<ListItem sx={sx}> <ListItem sx={sx}>

View File

@ -48,32 +48,36 @@ class DelayManager {
names: readonly string[]; names: readonly string[];
groupName: string; groupName: string;
skipNum: number; skipNum: number;
maxTimeout: number;
}, },
callback: Function callback: Function
) { ) {
let names = [...options.names]; const { groupName, skipNum } = options;
const { groupName, skipNum, maxTimeout } = options;
while (names.length) { const names = [...options.names];
const list = names.slice(0, skipNum); const total = names.length;
names = names.slice(skipNum);
let called = false; let count = 0;
setTimeout(() => { let current = 0;
if (!called) {
called = true;
callback();
}
}, maxTimeout);
await Promise.all(list.map((n) => this.checkDelay(n, groupName))); return new Promise((resolve) => {
const help = async (): Promise<void> => {
if (current >= skipNum) return;
if (!called) { const task = names.shift();
called = true; if (!task) return;
callback();
} current += 1;
} await this.checkDelay(task, groupName);
current -= 1;
if (count++ % skipNum === 0 || count === total) callback();
if (count === total) resolve(null);
return help();
};
for (let i = 0; i < skipNum; ++i) help();
});
} }
} }