prometheus

Форк
0
114 строк · 3.5 Кб
1
import { useState, useEffect } from 'react';
2
import { API_PATH } from '../constants/constants';
3
import { WALReplayStatus } from '../types/types';
4

5
export type APIResponse<T> = { status: string; data: T };
6

7
export interface FetchState<T> {
8
  response: APIResponse<T>;
9
  error?: Error;
10
  isLoading: boolean;
11
}
12

13
export interface FetchStateReadyInterval {
14
  ready: boolean;
15
  isUnexpected: boolean;
16
  walReplayStatus: WALReplayStatus;
17
}
18

19
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20
export const useFetch = <T extends Record<string, any>>(url: string, options?: RequestInit): FetchState<T> => {
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
  const [response, setResponse] = useState<APIResponse<T>>({ status: 'start fetching' } as any);
23
  const [error, setError] = useState<Error>();
24
  const [isLoading, setIsLoading] = useState<boolean>(true);
25

26
  useEffect(() => {
27
    const fetchData = async () => {
28
      setIsLoading(true);
29
      try {
30
        const res = await fetch(url, { cache: 'no-store', credentials: 'same-origin', ...options });
31
        if (!res.ok) {
32
          throw new Error(res.statusText);
33
        }
34
        const json = (await res.json()) as APIResponse<T>;
35
        setResponse(json);
36
        setIsLoading(false);
37
      } catch (err: unknown) {
38
        const error = err as Error;
39
        setError(error);
40
      }
41
    };
42
    fetchData();
43
  }, [url, options]);
44
  return { response, error, isLoading };
45
};
46

47
let wasReady = false;
48

49
// This is used on the starting page to periodically check if the server is ready yet,
50
// and check the status of the WAL replay.
51
export const useFetchReadyInterval = (pathPrefix: string, options?: RequestInit): FetchStateReadyInterval => {
52
  const [ready, setReady] = useState<boolean>(false);
53
  const [isUnexpected, setIsUnexpected] = useState<boolean>(false);
54
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
  const [walReplayStatus, setWALReplayStatus] = useState<WALReplayStatus>({} as any);
56

57
  useEffect(() => {
58
    if (wasReady) {
59
      setReady(true);
60
    } else {
61
      // This helps avoid a memory leak.
62
      let mounted = true;
63

64
      const fetchStatus = async () => {
65
        try {
66
          let res = await fetch(`${pathPrefix}/-/ready`, { cache: 'no-store', credentials: 'same-origin', ...options });
67
          if (res.status === 200) {
68
            if (mounted) {
69
              setReady(true);
70
            }
71
            wasReady = true;
72
            clearInterval(interval);
73
          } else if (res.status !== 503) {
74
            if (mounted) {
75
              setIsUnexpected(true);
76
            }
77
            clearInterval(interval);
78
            return;
79
          } else {
80
            if (mounted) {
81
              setIsUnexpected(false);
82
            }
83

84
            res = await fetch(`${pathPrefix}/${API_PATH}/status/walreplay`, {
85
              cache: 'no-store',
86
              credentials: 'same-origin',
87
            });
88
            if (res.ok) {
89
              const data = (await res.json()) as WALReplayStatus;
90
              if (mounted) {
91
                setWALReplayStatus(data);
92
              }
93
            }
94
          }
95
        } catch (error) {
96
          if (mounted) {
97
            setIsUnexpected(true);
98
          }
99
          clearInterval(interval);
100
          return;
101
        }
102
      };
103

104
      fetchStatus();
105
      const interval = setInterval(fetchStatus, 1000);
106
      return () => {
107
        clearInterval(interval);
108
        mounted = false;
109
      };
110
    }
111
  }, [pathPrefix, options]);
112

113
  return { ready, isUnexpected, walReplayStatus };
114
};
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.