Reconnect logs web socket on log level change
This commit is contained in:
parent
297fb101e7
commit
8c2af7a813
5 changed files with 41 additions and 39 deletions
|
@ -1,5 +1,6 @@
|
|||
import { pad0 } from 'src/misc/utils';
|
||||
import { Log, LogsAPIConfig } from 'src/types';
|
||||
import { Log } from 'src/store/types';
|
||||
import { LogsAPIConfig } from 'src/types';
|
||||
|
||||
import { buildLogsWebSocketURL, getURLAndInit } from '../misc/request-helper';
|
||||
|
||||
|
@ -15,6 +16,8 @@ const getRandomStr = () => {
|
|||
let even = false;
|
||||
let fetched = false;
|
||||
let decoded = '';
|
||||
let ws: WebSocket;
|
||||
let prevAppendLogFn: AppendLogFn;
|
||||
|
||||
function appendData(s: string, callback: AppendLogFn) {
|
||||
let o: Partial<Log>;
|
||||
|
@ -31,7 +34,7 @@ function appendData(s: string, callback: AppendLogFn) {
|
|||
o.time = time;
|
||||
o.id = +now - 0 + getRandomStr();
|
||||
o.even = even = !even;
|
||||
callback(o);
|
||||
callback(o as Log);
|
||||
}
|
||||
|
||||
function formatDate(d: Date) {
|
||||
|
@ -73,7 +76,14 @@ function pump(reader: ReadableStreamDefaultReader, appendLog: AppendLogFn) {
|
|||
});
|
||||
}
|
||||
|
||||
let apiConfigSnapshot: LogsAPIConfig;
|
||||
/** loose hashing of the connection configuration */
|
||||
function makeConnStr(c: LogsAPIConfig) {
|
||||
const keys = Object.keys(c);
|
||||
keys.sort();
|
||||
return keys.map((k) => c[k]).join('|');
|
||||
}
|
||||
|
||||
let prevConnStr: string;
|
||||
let controller: AbortController;
|
||||
|
||||
// 1 OPEN
|
||||
|
@ -84,11 +94,11 @@ let wsState: number;
|
|||
export function fetchLogs(apiConfig: LogsAPIConfig, appendLog: AppendLogFn) {
|
||||
if (apiConfig.logLevel === 'uninit') return;
|
||||
if (fetched || wsState === 1) return;
|
||||
prevAppendLogFn = appendLog;
|
||||
wsState = 1;
|
||||
const url = buildLogsWebSocketURL(apiConfig, endpoint);
|
||||
const ws = new WebSocket(url);
|
||||
ws.addEventListener('error', () => (wsState = 3));
|
||||
ws.addEventListener('close', function (_ev) {
|
||||
ws = new WebSocket(url);
|
||||
ws.addEventListener('error', () => {
|
||||
wsState = 3;
|
||||
fetchLogsWithFetch(apiConfig, appendLog);
|
||||
});
|
||||
|
@ -97,20 +107,23 @@ export function fetchLogs(apiConfig: LogsAPIConfig, appendLog: AppendLogFn) {
|
|||
});
|
||||
}
|
||||
|
||||
export function reconnect(apiConfig: LogsAPIConfig) {
|
||||
if (!prevAppendLogFn || !ws) return;
|
||||
ws.close();
|
||||
wsState = 3;
|
||||
fetched = false;
|
||||
fetchLogs(apiConfig, prevAppendLogFn);
|
||||
}
|
||||
|
||||
function fetchLogsWithFetch(apiConfig: LogsAPIConfig, appendLog: AppendLogFn) {
|
||||
if (
|
||||
controller &&
|
||||
(apiConfigSnapshot.baseURL !== apiConfig.baseURL ||
|
||||
apiConfigSnapshot.secret !== apiConfig.secret ||
|
||||
apiConfigSnapshot.logLevel !== apiConfig.logLevel)
|
||||
) {
|
||||
if (controller && makeConnStr(apiConfig) !== prevConnStr) {
|
||||
controller.abort();
|
||||
} else if (fetched) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetched = true;
|
||||
apiConfigSnapshot = { ...apiConfig };
|
||||
prevConnStr = makeConnStr(apiConfig);
|
||||
|
||||
controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import { LogOut } from 'react-feather';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import * as logsApi from 'src/api/logs';
|
||||
import Select from 'src/components/shared/Select';
|
||||
import { ClashGeneralConfig, DispatchFn, State } from 'src/store/types';
|
||||
import { ClashAPIConfig } from 'src/types';
|
||||
|
@ -103,10 +104,7 @@ function ConfigImpl({
|
|||
|
||||
const setConfigState = useCallback(
|
||||
(name, val) => {
|
||||
setConfigStateInternal({
|
||||
...configState,
|
||||
[name]: val,
|
||||
});
|
||||
setConfigStateInternal({ ...configState, [name]: val });
|
||||
},
|
||||
[configState]
|
||||
);
|
||||
|
@ -128,6 +126,9 @@ function ConfigImpl({
|
|||
case 'log-level':
|
||||
setConfigState(name, value);
|
||||
dispatch(updateConfigs(apiConfig, { [name]: value }));
|
||||
if (name === 'log-level') {
|
||||
logsApi.reconnect({ ...apiConfig, logLevel: value });
|
||||
}
|
||||
break;
|
||||
case 'redir-port':
|
||||
case 'socks-port':
|
||||
|
|
|
@ -15,7 +15,7 @@ import useRemainingViewPortHeight from 'src/hooks/useRemainingViewPortHeight';
|
|||
import { getClashAPIConfig } from 'src/store/app';
|
||||
import { getLogLevel } from 'src/store/configs';
|
||||
import { appendLog, getLogsForDisplay } from 'src/store/logs';
|
||||
import { Log,State } from 'src/store/types';
|
||||
import { Log, State } from 'src/store/types';
|
||||
|
||||
import s from './Logs.module.css';
|
||||
|
||||
|
@ -23,8 +23,7 @@ const { useCallback, memo, useEffect } = React;
|
|||
|
||||
const paddingBottom = 30;
|
||||
const colors = {
|
||||
debug: 'none',
|
||||
// debug: '#8a8a8a',
|
||||
debug: '#28792c',
|
||||
info: 'var(--bg-log-info-tag)',
|
||||
warning: '#b99105',
|
||||
error: '#c11c1c',
|
||||
|
@ -66,9 +65,7 @@ const Row = memo(
|
|||
|
||||
function Logs({ dispatch, logLevel, apiConfig, logs }) {
|
||||
const appendLogInternal = useCallback(
|
||||
(log) => {
|
||||
dispatch(appendLog(log));
|
||||
},
|
||||
(log) => dispatch(appendLog(log)),
|
||||
[dispatch]
|
||||
);
|
||||
useEffect(() => {
|
||||
|
|
|
@ -4,7 +4,6 @@ import Loading from 'src/components/Loading';
|
|||
|
||||
import Button from './Button';
|
||||
import Input from './Input';
|
||||
import { LoadingDot } from './shared/Basic';
|
||||
import SwitchThemed from './SwitchThemed';
|
||||
import ToggleSwitch from './ToggleSwitch';
|
||||
|
||||
|
@ -17,18 +16,9 @@ const paneStyle = {
|
|||
};
|
||||
|
||||
const optionsRule = [
|
||||
{
|
||||
label: 'Global',
|
||||
value: 'Global',
|
||||
},
|
||||
{
|
||||
label: 'Rule',
|
||||
value: 'Rule',
|
||||
},
|
||||
{
|
||||
label: 'Direct',
|
||||
value: 'Direct',
|
||||
},
|
||||
{ label: 'Global', value: 'Global' },
|
||||
{ label: 'Rule', value: 'Rule' },
|
||||
{ label: 'Direct', value: 'Direct' },
|
||||
];
|
||||
|
||||
const Pane = ({ children, style }) => (
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { createSelector } from 'reselect';
|
||||
|
||||
import { DispatchFn, GetStateFn, Log, State } from './types';
|
||||
import { DispatchFn, GetStateFn, Log, State } from 'src/store/types';
|
||||
|
||||
const LogSize = 300;
|
||||
|
||||
|
@ -44,7 +43,9 @@ export function appendLog(log: Log) {
|
|||
// mutate intentionally for performance
|
||||
logs[tail] = log;
|
||||
|
||||
dispatch('logsAppendLog', (s: State) => (s.logs.tail = tail));
|
||||
dispatch('logsAppendLog', (s: State) => {
|
||||
s.logs.tail = tail;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue