feat(proxy): single proxy node latency test

This commit is contained in:
kunish 2023-09-24 17:10:01 +08:00
parent dbbe2c10a7
commit 9255658e54
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
5 changed files with 73 additions and 17 deletions

View File

@ -30,9 +30,7 @@ const Config = lazy(() => import('~/pages/Config'))
const ProtectedResources = () => { const ProtectedResources = () => {
const latestConnectionMsg = useWsRequest<WsMsg>('connections') const latestConnectionMsg = useWsRequest<WsMsg>('connections')
createEffect(() => { createEffect(() => setLatestConnectionMsg(latestConnectionMsg()))
setLatestConnectionMsg(latestConnectionMsg())
})
return null return null
} }

View File

@ -146,6 +146,23 @@ export const selectProxyInGroupAPI = (groupName: string, proxyName: string) => {
}) })
} }
export const proxyLatencyTestAPI = (
proxyName: string,
url: string,
timeout: number,
) => {
const request = useRequest()
return request
.get(`proxies/${proxyName}/delay`, {
searchParams: {
url,
timeout,
},
})
.json<{ delay: number }>()
}
export const proxyGroupLatencyTestAPI = ( export const proxyGroupLatencyTestAPI = (
groupName: string, groupName: string,
url: string, url: string,

View File

@ -1,6 +1,7 @@
import { IconBrandSpeedtest } from '@tabler/icons-solidjs'
import { createMemo, Show } from 'solid-js' import { createMemo, Show } from 'solid-js'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { Latency } from '~/components' import { Button, Latency } from '~/components'
import { filterSpecialProxyType, formatProxyType } from '~/helpers' import { filterSpecialProxyType, formatProxyType } from '~/helpers'
import { useProxies } from '~/signals' import { useProxies } from '~/signals'
@ -9,6 +10,7 @@ export const ProxyNodeCard = (props: {
isSelected?: boolean isSelected?: boolean
onClick?: () => void onClick?: () => void
}) => { }) => {
const { proxyLatencyTest } = useProxies()
const { proxyName, isSelected, onClick } = props const { proxyName, isSelected, onClick } = props
const { proxyNodeMap } = useProxies() const { proxyNodeMap } = useProxies()
const proxyNode = createMemo(() => proxyNodeMap()[proxyName]) const proxyNode = createMemo(() => proxyNodeMap()[proxyName])
@ -28,10 +30,23 @@ export const ProxyNodeCard = (props: {
isSelected && 'border-primary bg-primary-content text-primary', isSelected && 'border-primary bg-primary-content text-primary',
onClick && 'cursor-pointer', onClick && 'cursor-pointer',
)} )}
onClick={() => onClick?.()} onClick={onClick}
data-tip={proxyName} data-tip={proxyName}
> >
<div class="truncate text-left">{proxyName}</div> <div class="flex items-center justify-between gap-2">
<span class="truncate text-left">{proxyName}</span>
<Button
class="btn-circle btn-ghost btn-sm"
icon={<IconBrandSpeedtest />}
onClick={(e) => {
e.stopPropagation()
void proxyLatencyTest(proxyName)
}}
/>
</div>
<div class="flex items-center justify-between gap-1"> <div class="flex items-center justify-between gap-1">
<div <div
class={twMerge( class={twMerge(
@ -40,8 +55,10 @@ export const ProxyNodeCard = (props: {
)} )}
> >
{formatProxyType(proxyNode()?.type)} {formatProxyType(proxyNode()?.type)}
<Show when={specialType()}>{` :: ${specialType()}`}</Show> <Show when={specialType()}>{` :: ${specialType()}`}</Show>
</div> </div>
<div class="text-xs"> <div class="text-xs">
<Latency name={props.proxyName} /> <Latency name={props.proxyName} />
</div> </div>

View File

@ -41,23 +41,23 @@ export default () => {
fetchProxies, fetchProxies,
proxies, proxies,
selectProxyInGroup, selectProxyInGroup,
latencyTestByProxyGroupName, proxyGroupLatencyTest,
latencyMap, latencyMap,
proxyProviders, proxyProviders,
updateProviderByProviderName, updateProviderByProviderName,
updateAllProvider, updateAllProvider,
healthCheckByProviderName, healthCheckByProviderName,
collapsedMap,
setCollapsedMap,
latencyTestingMap,
setLatencyTestingMap,
} = useProxies() } = useProxies()
onMount(fetchProxies) onMount(fetchProxies)
const { map: collapsedMap, set: setCollapsedMap } = useStringBooleanMap()
const { map: latencyTestingMap, setWithCallback: setLatencyTestingMap } =
useStringBooleanMap()
const onLatencyTestClick = async (e: MouseEvent, name: string) => { const onLatencyTestClick = async (e: MouseEvent, name: string) => {
e.stopPropagation() e.stopPropagation()
void setLatencyTestingMap(name, () => latencyTestByProxyGroupName(name)) void setLatencyTestingMap(name, () => proxyGroupLatencyTest(name))
} }
const { map: healthCheckingMap, setWithCallback: setHealthCheckingMap } = const { map: healthCheckingMap, setWithCallback: setHealthCheckingMap } =

View File

@ -4,10 +4,12 @@ import {
fetchProxiesAPI, fetchProxiesAPI,
fetchProxyProvidersAPI, fetchProxyProvidersAPI,
proxyGroupLatencyTestAPI, proxyGroupLatencyTestAPI,
proxyLatencyTestAPI,
proxyProviderHealthCheck, proxyProviderHealthCheck,
selectProxyInGroupAPI, selectProxyInGroupAPI,
updateProxyProviderAPI, updateProxyProviderAPI,
} from '~/apis' } from '~/apis'
import { useStringBooleanMap } from '~/helpers'
import { import {
autoCloseConns, autoCloseConns,
latencyQualityMap, latencyQualityMap,
@ -26,6 +28,10 @@ type ProxyInfo = {
type: string type: string
} }
const { map: collapsedMap, set: setCollapsedMap } = useStringBooleanMap()
const { map: latencyTestingMap, setWithCallback: setLatencyTestingMap } =
useStringBooleanMap()
// these signals should be global state // these signals should be global state
const [proxies, setProxies] = createSignal<Proxy[]>([]) const [proxies, setProxies] = createSignal<Proxy[]>([])
const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([]) const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([])
@ -113,17 +119,30 @@ export const useProxies = () => {
} }
} }
const latencyTestByProxyGroupName = async (proxyGroupName: string) => { const proxyLatencyTest = async (proxyName: string) => {
const { delay } = await proxyLatencyTestAPI(
proxyName,
urlForLatencyTest(),
latencyTestTimeoutDuration(),
)
setLatencyMap((latencyMap) => ({
...latencyMap,
[proxyName]: delay,
}))
}
const proxyGroupLatencyTest = async (proxyGroupName: string) => {
const data = await proxyGroupLatencyTestAPI( const data = await proxyGroupLatencyTestAPI(
proxyGroupName, proxyGroupName,
urlForLatencyTest(), urlForLatencyTest(),
latencyTestTimeoutDuration(), latencyTestTimeoutDuration(),
) )
setLatencyMap({ setLatencyMap((latencyMap) => ({
...latencyMap(), ...latencyMap,
...data, ...data,
}) }))
await fetchProxies() await fetchProxies()
} }
@ -148,9 +167,14 @@ export const useProxies = () => {
} }
return { return {
collapsedMap,
setCollapsedMap,
latencyTestingMap,
setLatencyTestingMap,
proxies, proxies,
proxyProviders, proxyProviders,
latencyTestByProxyGroupName, proxyLatencyTest,
proxyGroupLatencyTest,
latencyMap, latencyMap,
proxyNodeMap, proxyNodeMap,
fetchProxies, fetchProxies,