Skip to content

Commit 2f96f07

Browse files
committed
Use React hook to deal with websocket
1 parent 6cfb6ff commit 2f96f07

File tree

3 files changed

+73
-127
lines changed

3 files changed

+73
-127
lines changed

web-app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"react-pdf": "7.7.1",
2323
"react-redux": "^8.1.3",
2424
"react-router-dom": "6.22.3",
25+
"react-use-websocket": "^4.8.1",
2526
"react-virtualized": "^9.22.5",
2627
"react-window": "^1.8.10",
2728
"react-window-infinite-loader": "^1.0.9",

web-app/src/screens/Console/Trace/Trace.tsx

Lines changed: 64 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
import React, { Fragment, useEffect, useState } from "react";
17+
import { Fragment, useEffect, useState } from "react";
1818
import { DateTime } from "luxon";
1919
import { useSelector } from "react-redux";
2020
import {
@@ -37,20 +37,17 @@ import {
3737
traceMessageReceived,
3838
traceResetMessages,
3939
} from "./traceSlice";
40-
import { setHelpName } from "../../../systemSlice";
40+
import { setHelpName } from "systemSlice";
4141
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
4242
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
4343
import HelpMenu from "../HelpMenu";
44-
45-
var socket: any = null;
44+
import useWebSocket, { ReadyState } from "react-use-websocket";
4645

4746
const Trace = () => {
4847
const dispatch = useAppDispatch();
4948

5049
const messages = useSelector((state: AppState) => state.trace.messages);
51-
const traceStarted = useSelector(
52-
(state: AppState) => state.trace.traceStarted,
53-
);
50+
const traceStarted = useSelector((state: AppState) => state.trace.traceStarted);
5451

5552
const [statusCode, setStatusCode] = useState<string>("");
5653
const [method, setMethod] = useState<string>("");
@@ -65,74 +62,66 @@ const Trace = () => {
6562
const [errors, setErrors] = useState<boolean>(false);
6663

6764
const [toggleFilter, setToggleFilter] = useState<boolean>(false);
65+
const [logActive, setLogActive] = useState(false);
66+
const [wsUrl, setWsUrl] = useState<string>("");
6867

69-
const startTrace = () => {
70-
dispatch(traceResetMessages());
68+
useEffect(() => {
7169
const url = new URL(window.location.toString());
72-
const isDev = process.env.NODE_ENV === "development";
73-
const port = isDev ? "9090" : url.port;
74-
75-
let calls = `${s3 ? "s3," : ""}${internal ? "internal," : ""}${
76-
storage ? "storage," : ""
77-
}${os ? "os," : ""}`;
70+
const wsProt = wsProtocol(url.protocol);
71+
const port = process.env.NODE_ENV === "development" ? "9090" : url.port;
72+
const calls = all ? "all" : (() => {
73+
const c = [];
74+
if (s3) c.push("s3");
75+
if (internal) c.push("internal");
76+
if (storage) c.push("storage");
77+
if (os) c.push("os");
78+
return c.join(',');
79+
})();
7880

79-
if (all) {
80-
calls = "all";
81-
}
8281
// check if we are using base path, if not this always is `/`
83-
const baseLocation = new URL(document.baseURI);
84-
const baseUrl = baseLocation.pathname;
82+
const baseLocation = new URL(document.baseURI).pathname;
8583

86-
const wsProt = wsProtocol(url.protocol);
87-
socket = new WebSocket(
88-
`${wsProt}://${
89-
url.hostname
90-
}:${port}${baseUrl}ws/trace?calls=${calls}&threshold=${threshold}&onlyErrors=${
91-
errors ? "yes" : "no"
92-
}&statusCode=${statusCode}&method=${method}&funcname=${func}&path=${path}`,
93-
);
84+
const wsUrl = new URL(`${wsProt}://${url.hostname}:${port}${baseLocation}ws/trace`);
85+
wsUrl.searchParams.append("calls", calls);
86+
wsUrl.searchParams.append("threshold", threshold.toString());
87+
wsUrl.searchParams.append("onlyErrors", errors ? "yes" : "no");
88+
wsUrl.searchParams.append("statusCode", statusCode);
89+
wsUrl.searchParams.append("method", method);
90+
wsUrl.searchParams.append("funcname", func);
91+
wsUrl.searchParams.append("path", path);
92+
setWsUrl(wsUrl.href);
93+
}, [all, s3, internal, storage, os, threshold, errors, statusCode, method, func, path]);
9494

95-
let interval: any | null = null;
96-
if (socket !== null) {
97-
socket.onopen = () => {
98-
console.log("WebSocket Client Connected");
99-
dispatch(setTraceStarted(true));
100-
socket.send("ok");
101-
interval = setInterval(() => {
102-
socket.send("ok");
103-
}, 10 * 1000);
104-
};
105-
socket.onmessage = (message: MessageEvent) => {
106-
let m: TraceMessage = JSON.parse(message.data.toString());
95+
const {sendMessage, lastJsonMessage, readyState} = useWebSocket<TraceMessage>(wsUrl, {
96+
heartbeat: {
97+
message: "ok", interval: 10 * 1000, // send ok every 10 seconds
98+
timeout: 365 * 24 * 60 * 60 * 1000, // disconnect after 365 days (workaround, because heartbeat gets no response)
99+
}
100+
}, logActive);
107101

108-
m.ptime = DateTime.fromISO(m.time).toJSDate();
109-
m.key = Math.random();
110-
dispatch(traceMessageReceived(m));
111-
};
112-
socket.onclose = () => {
113-
clearInterval(interval);
114-
console.log("connection closed by server");
115-
dispatch(setTraceStarted(false));
116-
};
117-
return () => {
118-
socket.close(1000);
119-
clearInterval(interval);
120-
console.log("closing websockets");
121-
setTraceStarted(false);
122-
};
102+
useEffect(() => {
103+
if (readyState === ReadyState.CONNECTING) {
104+
dispatch(traceResetMessages());
105+
} else if (readyState === ReadyState.OPEN) {
106+
dispatch(setTraceStarted(true));
107+
} else if (readyState === ReadyState.CLOSED) {
108+
dispatch(setTraceStarted(false));
123109
}
124-
};
110+
}, [readyState, dispatch, sendMessage]);
125111

126-
const stopTrace = () => {
127-
socket.close(1000);
128-
dispatch(setTraceStarted(false));
129-
};
112+
useEffect(() => {
113+
if (lastJsonMessage) {
114+
lastJsonMessage.ptime = DateTime.fromISO(lastJsonMessage.time).toJSDate();
115+
lastJsonMessage.key = Math.random();
116+
dispatch(traceMessageReceived(lastJsonMessage));
117+
}
118+
}, [lastJsonMessage, dispatch])
130119

131120
useEffect(() => {
132121
dispatch(setHelpName("trace"));
133122
// eslint-disable-next-line react-hooks/exhaustive-deps
134123
}, []);
135-
124+
136125
return (
137126
<Fragment>
138127
<PageHeaderWrapper label={"Trace"} actions={<HelpMenu />} />
@@ -187,9 +176,7 @@ const Trace = () => {
187176
id={"all_calls"}
188177
name={"all_calls"}
189178
label={"All"}
190-
onChange={() => {
191-
setAll(!all);
192-
}}
179+
onChange={() => setAll(!all)}
193180
value={"all"}
194181
disabled={traceStarted}
195182
/>
@@ -198,9 +185,7 @@ const Trace = () => {
198185
id={"s3_calls"}
199186
name={"s3_calls"}
200187
label={"S3"}
201-
onChange={() => {
202-
setS3(!s3);
203-
}}
188+
onChange={() => setS3(!s3)}
204189
value={"s3"}
205190
disabled={all || traceStarted}
206191
/>
@@ -209,9 +194,7 @@ const Trace = () => {
209194
id={"internal_calls"}
210195
name={"internal_calls"}
211196
label={"Internal"}
212-
onChange={() => {
213-
setInternal(!internal);
214-
}}
197+
onChange={() => setInternal(!internal)}
215198
value={"internal"}
216199
disabled={all || traceStarted}
217200
/>
@@ -220,9 +203,7 @@ const Trace = () => {
220203
id={"storage_calls"}
221204
name={"storage_calls"}
222205
label={"Storage"}
223-
onChange={() => {
224-
setStorage(!storage);
225-
}}
206+
onChange={() => setStorage(!storage)}
226207
value={"storage"}
227208
disabled={all || traceStarted}
228209
/>
@@ -231,9 +212,7 @@ const Trace = () => {
231212
id={"os_calls"}
232213
name={"os_calls"}
233214
label={"OS"}
234-
onChange={() => {
235-
setOS(!os);
236-
}}
215+
onChange={() => setOS(!os)}
237216
value={"os"}
238217
disabled={all || traceStarted}
239218
/>
@@ -249,9 +228,7 @@ const Trace = () => {
249228
<TooltipWrapper tooltip={"More filter options"}>
250229
<Button
251230
id={"filter-toggle"}
252-
onClick={() => {
253-
setToggleFilter(!toggleFilter);
254-
}}
231+
onClick={() => setToggleFilter(!toggleFilter)}
255232
label={"Filters"}
256233
icon={<FilterIcon />}
257234
variant={"regular"}
@@ -269,7 +246,7 @@ const Trace = () => {
269246
label={"Start"}
270247
data-test-id={"trace-start-button"}
271248
variant="callAction"
272-
onClick={startTrace}
249+
onClick={() => setLogActive(true)}
273250
style={{
274251
width: "118px",
275252
}}
@@ -281,7 +258,7 @@ const Trace = () => {
281258
label={"Stop Trace"}
282259
data-test-id={"trace-stop-button"}
283260
variant="callAction"
284-
onClick={stopTrace}
261+
onClick={() => setLogActive(false)}
285262
style={{
286263
width: "118px",
287264
}}
@@ -330,9 +307,7 @@ const Trace = () => {
330307
label="Status Code"
331308
placeholder="e.g. 503"
332309
value={statusCode}
333-
onChange={(e) => {
334-
setStatusCode(e.target.value);
335-
}}
310+
onChange={(e) => setStatusCode(e.target.value)}
336311
disabled={traceStarted}
337312
/>
338313

@@ -343,9 +318,7 @@ const Trace = () => {
343318
label="Function Name"
344319
placeholder="e.g. FunctionName2055"
345320
value={func}
346-
onChange={(e) => {
347-
setFunc(e.target.value);
348-
}}
321+
onChange={(e) => setFunc(e.target.value)}
349322
disabled={traceStarted}
350323
/>
351324

@@ -356,9 +329,7 @@ const Trace = () => {
356329
label="Method"
357330
placeholder="e.g. Method 2056"
358331
value={method}
359-
onChange={(e) => {
360-
setMethod(e.target.value);
361-
}}
332+
onChange={(e) => setMethod(e.target.value)}
362333
disabled={traceStarted}
363334
/>
364335
</Box>
@@ -384,9 +355,7 @@ const Trace = () => {
384355
label="Path"
385356
placeholder="e.g. my-bucket/my-prefix/*"
386357
value={path}
387-
onChange={(e) => {
388-
setPath(e.target.value);
389-
}}
358+
onChange={(e) => setPath(e.target.value)}
390359
disabled={traceStarted}
391360
/>
392361
</Box>
@@ -403,9 +372,7 @@ const Trace = () => {
403372
type="number"
404373
placeholder="e.g. website.io.3249.114.12"
405374
value={`${threshold}`}
406-
onChange={(e) => {
407-
setThreshold(parseInt(e.target.value));
408-
}}
375+
onChange={(e) => setThreshold(parseInt(e.target.value))}
409376
disabled={traceStarted}
410377
/>
411378
</Box>
@@ -423,9 +390,7 @@ const Trace = () => {
423390
id={"only_errors"}
424391
name={"only_errors"}
425392
label={"Display only Errors"}
426-
onChange={() => {
427-
setErrors(!errors);
428-
}}
393+
onChange={() => setErrors(!errors)}
429394
value={"only_errors"}
430395
disabled={traceStarted}
431396
/>

web-app/yarn.lock

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10429,6 +10429,11 @@ react-transition-group@^4.4.5:
1042910429
loose-envify "^1.4.0"
1043010430
prop-types "^15.6.2"
1043110431

10432+
react-use-websocket@^4.8.1:
10433+
version "4.8.1"
10434+
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-4.8.1.tgz#be06a0bc956c6d56391a29cbe2caa6ae8edb5615"
10435+
integrity sha512-FTXuG5O+LFozmu1BRfrzl7UIQngECvGJmL7BHsK4TYXuVt+mCizVA8lT0hGSIF0Z0TedF7bOo1nRzOUdginhDw==
10436+
1043210437
react-virtual@^2.8.2:
1043310438
version "2.10.4"
1043410439
resolved "https://registry.yarnpkg.com/react-virtual/-/react-virtual-2.10.4.tgz#08712f0acd79d7d6f7c4726f05651a13b24d8704"
@@ -11399,16 +11404,7 @@ string-natural-compare@^3.0.1:
1139911404
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
1140011405
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
1140111406

11402-
"string-width-cjs@npm:string-width@^4.2.0":
11403-
version "4.2.3"
11404-
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
11405-
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
11406-
dependencies:
11407-
emoji-regex "^8.0.0"
11408-
is-fullwidth-code-point "^3.0.0"
11409-
strip-ansi "^6.0.1"
11410-
11411-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
11407+
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
1141211408
version "4.2.3"
1141311409
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
1141411410
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11503,14 +11499,7 @@ stringify-object@^3.3.0:
1150311499
is-obj "^1.0.1"
1150411500
is-regexp "^1.0.0"
1150511501

11506-
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
11507-
version "6.0.1"
11508-
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
11509-
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
11510-
dependencies:
11511-
ansi-regex "^5.0.1"
11512-
11513-
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
11502+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
1151411503
version "6.0.1"
1151511504
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
1151611505
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -13260,7 +13249,7 @@ [email protected]:
1326013249
"@types/trusted-types" "^2.0.2"
1326113250
workbox-core "6.6.1"
1326213251

13263-
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
13252+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
1326413253
version "7.0.0"
1326513254
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
1326613255
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -13278,15 +13267,6 @@ wrap-ansi@^6.2.0:
1327813267
string-width "^4.1.0"
1327913268
strip-ansi "^6.0.0"
1328013269

13281-
wrap-ansi@^7.0.0:
13282-
version "7.0.0"
13283-
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
13284-
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
13285-
dependencies:
13286-
ansi-styles "^4.0.0"
13287-
string-width "^4.1.0"
13288-
strip-ansi "^6.0.0"
13289-
1329013270
wrap-ansi@^8.1.0:
1329113271
version "8.1.0"
1329213272
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"

0 commit comments

Comments
 (0)