pi-kiosk-shared 2.1.14 → 2.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
interface UseDatabaseHealthOptions {
|
|
2
|
-
healthEndpoint?: string;
|
|
3
2
|
pollInterval?: number;
|
|
4
3
|
maxRetries?: number;
|
|
5
4
|
retryDelay?: number;
|
|
@@ -13,10 +12,6 @@ interface UseDatabaseHealthReturn {
|
|
|
13
12
|
error: Error | null;
|
|
14
13
|
checkHealth: () => Promise<void>;
|
|
15
14
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Hook to monitor database health via backend health endpoint
|
|
18
|
-
* Implements exponential backoff retry logic
|
|
19
|
-
*/
|
|
20
15
|
export declare function useDatabaseHealth(options?: UseDatabaseHealthOptions): UseDatabaseHealthReturn;
|
|
21
16
|
export {};
|
|
22
17
|
//# sourceMappingURL=useDatabaseHealth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDatabaseHealth.d.ts","sourceRoot":"","sources":["../../src/hooks/useDatabaseHealth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDatabaseHealth.d.ts","sourceRoot":"","sources":["../../src/hooks/useDatabaseHealth.ts"],"names":[],"mappings":"AAOA,UAAU,wBAAwB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,uBAAuB;IAC/B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,uBAAuB,CAoIzB"}
|
|
@@ -1,104 +1,80 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Hook to monitor database health via backend health endpoint
|
|
4
|
-
* Implements exponential backoff retry logic
|
|
5
|
-
*/
|
|
6
2
|
export function useDatabaseHealth(options = {}) {
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
enabled = true, } = options;
|
|
10
|
-
const [isDatabaseAvailable, setIsDatabaseAvailable] = useState(true); // Default to true initially
|
|
3
|
+
const { pollInterval = 5000, maxRetries = 5, retryDelay = 1000, enabled = true, } = options;
|
|
4
|
+
const [isDatabaseAvailable, setIsDatabaseAvailable] = useState(true);
|
|
11
5
|
const [isChecking, setIsChecking] = useState(false);
|
|
12
6
|
const [retryCount, setRetryCount] = useState(0);
|
|
13
7
|
const [nextRetryDelay, setNextRetryDelay] = useState(0);
|
|
14
8
|
const [error, setError] = useState(null);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
const [healthEndpoint, setHealthEndpoint] = useState('http://localhost:3015/health');
|
|
10
|
+
// Initialize health endpoint URL from runtime config
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (typeof window !== 'undefined') {
|
|
13
|
+
const windowConfig = window.__RUNTIME_CONFIG__;
|
|
14
|
+
const apiUrl = windowConfig?.apiUrl;
|
|
15
|
+
if (apiUrl) {
|
|
16
|
+
setHealthEndpoint(`${apiUrl}/health`);
|
|
17
|
+
console.log('[DatabaseHealth] Using API URL:', `${apiUrl}/health`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}, []);
|
|
21
|
+
const retryCountRef = useRef(0);
|
|
18
22
|
const backoffMultiplierRef = useRef(2);
|
|
19
23
|
const currentDelayRef = useRef(retryDelay);
|
|
24
|
+
const pollTimeoutRef = useRef(null);
|
|
25
|
+
const retryTimeoutRef = useRef(null);
|
|
20
26
|
const checkHealth = useCallback(async () => {
|
|
21
27
|
if (!enabled)
|
|
22
28
|
return;
|
|
23
29
|
setIsChecking(true);
|
|
24
30
|
setError(null);
|
|
31
|
+
console.log('[DatabaseHealth] Checking health at:', healthEndpoint);
|
|
25
32
|
try {
|
|
26
33
|
const response = await fetch(healthEndpoint, {
|
|
27
34
|
method: 'GET',
|
|
28
|
-
headers: {
|
|
29
|
-
'Content-Type': 'application/json',
|
|
30
|
-
},
|
|
31
|
-
// Add cache-busting to prevent stale responses
|
|
35
|
+
headers: { 'Content-Type': 'application/json' },
|
|
32
36
|
cache: 'no-cache',
|
|
33
37
|
});
|
|
34
38
|
if (!response.ok) {
|
|
35
39
|
throw new Error(`Health check failed: ${response.status} ${response.statusText}`);
|
|
36
40
|
}
|
|
41
|
+
const contentType = response.headers.get('content-type');
|
|
42
|
+
if (!contentType?.includes('application/json')) {
|
|
43
|
+
const text = await response.text();
|
|
44
|
+
console.error('[DatabaseHealth] Invalid response type:', { contentType, preview: text.substring(0, 100) });
|
|
45
|
+
throw new Error(`Invalid response: expected JSON, got ${contentType}`);
|
|
46
|
+
}
|
|
37
47
|
const data = (await response.json());
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Check if database service is healthy
|
|
41
|
-
// The health endpoint returns success: true when healthy
|
|
42
|
-
const isDbHealthy = data.success === true;
|
|
43
|
-
if (isDbHealthy) {
|
|
44
|
-
// Database is available - reset retry state
|
|
48
|
+
console.log('[DatabaseHealth] Health response:', { success: data.success, status: data.status });
|
|
49
|
+
if (data.success === true) {
|
|
45
50
|
setIsDatabaseAvailable(true);
|
|
46
51
|
setRetryCount(0);
|
|
47
52
|
setNextRetryDelay(0);
|
|
48
|
-
|
|
53
|
+
retryCountRef.current = 0;
|
|
49
54
|
currentDelayRef.current = retryDelay;
|
|
50
55
|
backoffMultiplierRef.current = 2;
|
|
51
56
|
}
|
|
52
57
|
else {
|
|
53
|
-
|
|
54
|
-
setIsDatabaseAvailable(false);
|
|
55
|
-
// Increment retry count
|
|
56
|
-
const newRetryCount = currentRetryCountRef.current + 1;
|
|
57
|
-
currentRetryCountRef.current = newRetryCount;
|
|
58
|
-
setRetryCount(newRetryCount);
|
|
59
|
-
if (newRetryCount < maxRetries) {
|
|
60
|
-
// Calculate next delay with exponential backoff
|
|
61
|
-
const nextDelay = Math.min(currentDelayRef.current * backoffMultiplierRef.current, retryDelay * 30 // Cap at 30x initial delay
|
|
62
|
-
);
|
|
63
|
-
currentDelayRef.current = nextDelay;
|
|
64
|
-
setNextRetryDelay(nextDelay);
|
|
65
|
-
// Schedule next retry
|
|
66
|
-
retryTimeoutRef.current = setTimeout(() => {
|
|
67
|
-
void checkHealth();
|
|
68
|
-
}, nextDelay);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
// Max retries reached - continue polling at regular interval
|
|
72
|
-
setNextRetryDelay(pollInterval);
|
|
73
|
-
retryTimeoutRef.current = setTimeout(() => {
|
|
74
|
-
void checkHealth();
|
|
75
|
-
}, pollInterval);
|
|
76
|
-
}
|
|
58
|
+
throw new Error('Database reported unhealthy status');
|
|
77
59
|
}
|
|
78
60
|
}
|
|
79
61
|
catch (err) {
|
|
80
|
-
|
|
81
|
-
const error = err instanceof Error ? err : new Error('Failed to check database health');
|
|
62
|
+
const error = err instanceof Error ? err : new Error('Health check failed');
|
|
82
63
|
console.error('[DatabaseHealth] Health check error:', error);
|
|
83
64
|
setError(error);
|
|
84
65
|
setIsDatabaseAvailable(false);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
currentRetryCountRef.current = newRetryCount;
|
|
66
|
+
const newRetryCount = retryCountRef.current + 1;
|
|
67
|
+
retryCountRef.current = newRetryCount;
|
|
88
68
|
setRetryCount(newRetryCount);
|
|
89
69
|
if (newRetryCount < maxRetries) {
|
|
90
|
-
|
|
91
|
-
const nextDelay = Math.min(currentDelayRef.current * backoffMultiplierRef.current, retryDelay * 30 // Cap at 30x initial delay
|
|
92
|
-
);
|
|
70
|
+
const nextDelay = Math.min(currentDelayRef.current * backoffMultiplierRef.current, retryDelay * 30);
|
|
93
71
|
currentDelayRef.current = nextDelay;
|
|
94
72
|
setNextRetryDelay(nextDelay);
|
|
95
|
-
// Schedule next retry
|
|
96
73
|
retryTimeoutRef.current = setTimeout(() => {
|
|
97
74
|
void checkHealth();
|
|
98
75
|
}, nextDelay);
|
|
99
76
|
}
|
|
100
77
|
else {
|
|
101
|
-
// Max retries reached - continue polling at regular interval
|
|
102
78
|
setNextRetryDelay(pollInterval);
|
|
103
79
|
retryTimeoutRef.current = setTimeout(() => {
|
|
104
80
|
void checkHealth();
|
|
@@ -109,34 +85,28 @@ export function useDatabaseHealth(options = {}) {
|
|
|
109
85
|
setIsChecking(false);
|
|
110
86
|
}
|
|
111
87
|
}, [enabled, healthEndpoint, maxRetries, retryDelay, pollInterval]);
|
|
112
|
-
// Initial health check and polling
|
|
113
88
|
useEffect(() => {
|
|
114
89
|
if (!enabled)
|
|
115
90
|
return;
|
|
116
91
|
// Initial check
|
|
117
92
|
void checkHealth();
|
|
118
|
-
//
|
|
93
|
+
// Polling
|
|
119
94
|
const startPolling = () => {
|
|
120
|
-
if (pollTimeoutRef.current)
|
|
95
|
+
if (pollTimeoutRef.current)
|
|
121
96
|
clearTimeout(pollTimeoutRef.current);
|
|
122
|
-
}
|
|
123
97
|
pollTimeoutRef.current = setTimeout(() => {
|
|
124
|
-
|
|
125
|
-
void checkHealth();
|
|
126
|
-
}
|
|
98
|
+
void checkHealth();
|
|
127
99
|
startPolling();
|
|
128
100
|
}, pollInterval);
|
|
129
101
|
};
|
|
130
102
|
startPolling();
|
|
131
103
|
return () => {
|
|
132
|
-
if (pollTimeoutRef.current)
|
|
104
|
+
if (pollTimeoutRef.current)
|
|
133
105
|
clearTimeout(pollTimeoutRef.current);
|
|
134
|
-
|
|
135
|
-
if (retryTimeoutRef.current) {
|
|
106
|
+
if (retryTimeoutRef.current)
|
|
136
107
|
clearTimeout(retryTimeoutRef.current);
|
|
137
|
-
}
|
|
138
108
|
};
|
|
139
|
-
}, [enabled, checkHealth,
|
|
109
|
+
}, [enabled, checkHealth, pollInterval]);
|
|
140
110
|
return {
|
|
141
111
|
isDatabaseAvailable,
|
|
142
112
|
isChecking,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDatabaseHealth.js","sourceRoot":"","sources":["../../src/hooks/useDatabaseHealth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useDatabaseHealth.js","sourceRoot":"","sources":["../../src/hooks/useDatabaseHealth.ts"],"names":[],"mappings":"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"}
|