delay.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { getProxyDelay } from "./api";
  2. const hashKey = (name: string, group: string) => `${group ?? ""}::${name}`;
  3. class DelayManager {
  4. private cache = new Map<string, [number, number]>();
  5. private urlMap = new Map<string, string>();
  6. setUrl(group: string, url: string) {
  7. this.urlMap.set(group, url);
  8. }
  9. getUrl(group: string) {
  10. return this.urlMap.get(group);
  11. }
  12. setDelay(name: string, group: string, delay: number) {
  13. this.cache.set(hashKey(name, group), [Date.now(), delay]);
  14. }
  15. getDelay(name: string, group: string) {
  16. if (!name) return -1;
  17. const result = this.cache.get(hashKey(name, group));
  18. if (result && Date.now() - result[0] <= 18e5) {
  19. return result[1];
  20. }
  21. return -1;
  22. }
  23. async checkDelay(name: string, group: string) {
  24. let delay = -1;
  25. try {
  26. const url = this.getUrl(group);
  27. const result = await getProxyDelay(name, url);
  28. delay = result.delay;
  29. } catch {
  30. delay = 1e6; // error
  31. }
  32. this.setDelay(name, group, delay);
  33. return delay;
  34. }
  35. async checkListDelay(
  36. options: {
  37. names: readonly string[];
  38. groupName: string;
  39. skipNum: number;
  40. },
  41. callback: Function
  42. ) {
  43. const { groupName, skipNum } = options;
  44. const names = [...options.names];
  45. const total = names.length;
  46. let count = 0;
  47. let current = 0;
  48. // 设置正在延迟测试中
  49. names.forEach((name) => this.setDelay(name, groupName, -2));
  50. return new Promise((resolve) => {
  51. const help = async (): Promise<void> => {
  52. if (current >= skipNum) return;
  53. const task = names.shift();
  54. if (!task) return;
  55. current += 1;
  56. await this.checkDelay(task, groupName);
  57. current -= 1;
  58. if (count++ % skipNum === 0 || count === total) callback();
  59. if (count === total) resolve(null);
  60. return help();
  61. };
  62. for (let i = 0; i < skipNum; ++i) help();
  63. });
  64. }
  65. }
  66. export default new DelayManager();