mirror of
https://gitee.com/arthas/arthas.git
synced 2024-11-29 18:58:37 +08:00
perf(web ui):keep alive consumer (#2325)
This commit is contained in:
parent
aa2526075b
commit
18e8f6b5d8
5
web-ui/arthasWebConsole/ui/src/arthas.d.ts
vendored
5
web-ui/arthasWebConsole/ui/src/arthas.d.ts
vendored
@ -422,6 +422,7 @@ type CommandResult = {
|
|||||||
} | {
|
} | {
|
||||||
options: GlobalOptions[];
|
options: GlobalOptions[];
|
||||||
changeResult: {
|
changeResult: {
|
||||||
|
|
||||||
"afterValue": unknown,
|
"afterValue": unknown,
|
||||||
"beforeValue": unknown,
|
"beforeValue": unknown,
|
||||||
"name": string
|
"name": string
|
||||||
@ -709,7 +710,9 @@ type ArthasRes = CommonRes | SessionRes | FailRes | AsyncRes;
|
|||||||
type BindQS =
|
type BindQS =
|
||||||
| { req: CommandReq; res: CommonRes }
|
| { req: CommandReq; res: CommonRes }
|
||||||
| { req: SessionReq; res: SessionRes }
|
| { req: SessionReq; res: SessionRes }
|
||||||
| { req: AsyncReq; res: AsyncRes };
|
| { req: AsyncReq; res: AsyncRes }
|
||||||
|
| { req: PullResults; res: ArthasRes };
|
||||||
|
|
||||||
// autoComplete
|
// autoComplete
|
||||||
type Item = { name: string; value: unknown };
|
type Item = { name: string; value: unknown };
|
||||||
|
|
||||||
|
@ -26,7 +26,10 @@ publicS.getCommonResEffect(fetchM, body => {
|
|||||||
const result = body.results[0]
|
const result = body.results[0]
|
||||||
if (result.type === "version") {
|
if (result.type === "version") {
|
||||||
version.value = result.version
|
version.value = result.version
|
||||||
}})
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!fetchS.wait) restBtnclass.value = "animate-spin-rev-pause"
|
if (!fetchS.wait) restBtnclass.value = "animate-spin-rev-pause"
|
||||||
@ -68,20 +71,12 @@ const logout = async () => {
|
|||||||
|
|
||||||
interruptEvent()
|
interruptEvent()
|
||||||
|
|
||||||
sessionM.send("SUBMIT", {
|
fetchS.closeSession()
|
||||||
value: {
|
|
||||||
action: "close_session",
|
|
||||||
sessionId: undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
restBtnclass.value = "animate-spin-rev-pause"
|
restBtnclass.value = "animate-spin-rev-pause"
|
||||||
}
|
}
|
||||||
const login = async () => {
|
|
||||||
sessionM.send("SUBMIT", {
|
const login = () => {
|
||||||
value: {
|
fetchS.initSession()
|
||||||
action: "init_session"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
const shutdown = () => {
|
const shutdown = () => {
|
||||||
publicS.warnMessage = "Are you sure to stop the arthas? All the Arthas clients connecting to this server will be disconnected."
|
publicS.warnMessage = "Are you sure to stop the arthas? All the Arthas clients connecting to this server will be disconnected."
|
||||||
@ -134,6 +129,7 @@ const tabs = [
|
|||||||
icon: TerminalIcon
|
icon: TerminalIcon
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
name:'terminal',
|
name:'terminal',
|
||||||
url:'terminal',
|
url:'terminal',
|
||||||
icon:TerminalIcon
|
icon:TerminalIcon
|
||||||
@ -148,8 +144,8 @@ const tools: [string, () => void][] = [
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const routePath = computed(() => useRoute().path)
|
const routePath = computed(() => useRoute().path)
|
||||||
const toNext = (url: string) => {
|
const toNext = (url: string) => {
|
||||||
if(url === "terminal") {
|
if (url === "terminal") {
|
||||||
window.open("/","_blank")
|
window.open("/", "_blank")
|
||||||
} else router.push(url)
|
} else router.push(url)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -158,11 +154,11 @@ const toNext = (url: string) => {
|
|||||||
<nav class=" h-[10vh] border-b-2 navbar">
|
<nav class=" h-[10vh] border-b-2 navbar">
|
||||||
<div class=" navbar-start flex items-stretch ">
|
<div class=" navbar-start flex items-stretch ">
|
||||||
<!-- <div class=" indicator mx-3"> -->
|
<!-- <div class=" indicator mx-3"> -->
|
||||||
<a class="flex items-center justify-center mx-2" href="https://arthas.aliyun.com/doc/commands.html"
|
<a class="flex items-center justify-center mx-2" href="https://arthas.aliyun.com/doc/commands.html"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<img src="/arthas.png" alt="logo" class="w-32" />
|
<img src="/arthas.png" alt="logo" class="w-32" />
|
||||||
</a>
|
</a>
|
||||||
<span class="badge badge-ghost self-end text-sm">v{{version}}</span>
|
<span class="badge badge-ghost self-end text-sm">v{{ version }}</span>
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-center">
|
<div class="navbar-center">
|
||||||
@ -171,7 +167,7 @@ const toNext = (url: string) => {
|
|||||||
<a class="break-all" :class="{ 'bg-primary text-primary-content': routePath.includes(tab.url), }">
|
<a class="break-all" :class="{ 'bg-primary text-primary-content': routePath.includes(tab.url), }">
|
||||||
<component :is="tab.icon" class="w-4 h-4" />
|
<component :is="tab.icon" class="w-4 h-4" />
|
||||||
{{
|
{{
|
||||||
tab.name
|
tab.name
|
||||||
}}
|
}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -443,7 +443,7 @@ const permachine = createMachine({
|
|||||||
isCommon: (context) => {
|
isCommon: (context) => {
|
||||||
if (!context) return false;
|
if (!context) return false;
|
||||||
if (
|
if (
|
||||||
["exec"]
|
["exec","pull_results"]
|
||||||
.includes(context.inputValue!.action)
|
.includes(context.inputValue!.action)
|
||||||
) {
|
) {
|
||||||
console.log("isCommon");
|
console.log("isCommon");
|
||||||
@ -454,7 +454,7 @@ const permachine = createMachine({
|
|||||||
isAsync: (context) => {
|
isAsync: (context) => {
|
||||||
if (!context) return false;
|
if (!context) return false;
|
||||||
if (
|
if (
|
||||||
["async_exec", "pull_results"]
|
["async_exec"]
|
||||||
.includes(context.inputValue!.action)
|
.includes(context.inputValue!.action)
|
||||||
) {
|
) {
|
||||||
console.log("isAsync");
|
console.log("isAsync");
|
||||||
|
@ -12,6 +12,10 @@ const router = createRouter({
|
|||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
fetchStore()
|
fetchStore()
|
||||||
.interruptJob()
|
.interruptJob()
|
||||||
|
.catch(_=>{
|
||||||
|
// console.error(e)
|
||||||
|
// 拦截调试台的错误
|
||||||
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,8 @@ type PollingLoop = {
|
|||||||
invoke(): void;
|
invoke(): void;
|
||||||
};
|
};
|
||||||
const nullLoop: PollingLoop = {
|
const nullLoop: PollingLoop = {
|
||||||
open() {},
|
open() {
|
||||||
|
},
|
||||||
close() {},
|
close() {},
|
||||||
isOn() {
|
isOn() {
|
||||||
return false;
|
return false;
|
||||||
@ -48,11 +49,11 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
// 所有用pollingLoop都要
|
// 所有用pollingLoop都要
|
||||||
jobRunning: false,
|
jobRunning: false,
|
||||||
// 对于 pullresults可能会拉同一个结果很多次
|
// 对于 pullresults可能会拉同一个结果很多次
|
||||||
jobIdSet: new Set<string>(),
|
// jobIdSet: new Set<string>(),
|
||||||
//由于轮询只会轮询一个命令,可以直接挂载当前的轮询机
|
//由于轮询只会轮询一个命令,可以直接挂载当前的轮询机
|
||||||
curPolling: nullLoop,
|
curPolling: nullLoop,
|
||||||
//获取osName 通过dashboard
|
//对session init以后4分钟重轮一次。
|
||||||
osName:""
|
// 如果curPolling是nullLoop,就要停掉状态维持来防止消耗异步请求结果的行为
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getRequest: (state) =>
|
getRequest: (state) =>
|
||||||
@ -94,6 +95,15 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
/**
|
||||||
|
* @param hander 要使用的函数
|
||||||
|
* @param options step:间隔时间,globalIntrupt: 是否需要全局的打断按钮
|
||||||
|
* @returns 一个轮询对象
|
||||||
|
* 需要open以后才挂载到curPolling
|
||||||
|
* close以后会重置为nullLoop
|
||||||
|
* curloop的状态转移
|
||||||
|
* nullloop->keepalive loop->polling loop
|
||||||
|
*/
|
||||||
getPollingLoop(
|
getPollingLoop(
|
||||||
hander: Function,
|
hander: Function,
|
||||||
options: { step?: number; globalIntrupt?: boolean } = {
|
options: { step?: number; globalIntrupt?: boolean } = {
|
||||||
@ -104,10 +114,16 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
let id = -1;
|
let id = -1;
|
||||||
const { step, globalIntrupt } = options;
|
const { step, globalIntrupt } = options;
|
||||||
const that = this;
|
const that = this;
|
||||||
const pollingLoop = {
|
// 很有可能是keepalive session loop
|
||||||
|
let preLoop = this.curPolling;
|
||||||
|
const pollingLoop: PollingLoop = {
|
||||||
// 自动轮询的可能会被错误打断
|
// 自动轮询的可能会被错误打断
|
||||||
open() {
|
open() {
|
||||||
if (!this.isOn()) {
|
if (!this.isOn()) {
|
||||||
|
// 切换为当前用到的 pollingLoop
|
||||||
|
preLoop.close();
|
||||||
|
that.curPolling = pollingLoop;
|
||||||
|
|
||||||
if (globalIntrupt) that.jobRunning = true;
|
if (globalIntrupt) that.jobRunning = true;
|
||||||
hander();
|
hander();
|
||||||
id = setInterval(
|
id = setInterval(
|
||||||
@ -131,6 +147,10 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
if (globalIntrupt) that.jobRunning = false;
|
if (globalIntrupt) that.jobRunning = false;
|
||||||
clearInterval(id);
|
clearInterval(id);
|
||||||
id = -1;
|
id = -1;
|
||||||
|
// 重置为默认的nullloop
|
||||||
|
that.curPolling = preLoop;
|
||||||
|
// 继续keepalive
|
||||||
|
preLoop.open();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isOn() {
|
isOn() {
|
||||||
@ -143,10 +163,9 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
hander();
|
hander();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
this.curPolling = pollingLoop;
|
|
||||||
return pollingLoop;
|
return pollingLoop;
|
||||||
},
|
},
|
||||||
pullResultsLoop(pollingM: Machine,globalIntrupt:boolean=true) {
|
pullResultsLoop(pollingM: Machine, globalIntrupt: boolean = true) {
|
||||||
return this.getPollingLoop(
|
return this.getPollingLoop(
|
||||||
() => {
|
() => {
|
||||||
pollingM.send({
|
pollingM.send({
|
||||||
@ -163,6 +182,9 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 用来提示是否正在请求中
|
||||||
|
*/
|
||||||
onWait() {
|
onWait() {
|
||||||
if (!this.wait) this.wait = true;
|
if (!this.wait) this.wait = true;
|
||||||
},
|
},
|
||||||
@ -245,10 +267,71 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
keepaliveSession() {
|
||||||
|
const kl = () => {
|
||||||
|
let m = interpret(permachine);
|
||||||
|
m.start();
|
||||||
|
m.send("INIT");
|
||||||
|
m.send({
|
||||||
|
type: "SUBMIT",
|
||||||
|
value: {
|
||||||
|
action: "pull_results",
|
||||||
|
sessionId: undefined,
|
||||||
|
consumerId: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
kl();
|
||||||
|
let id = -1;
|
||||||
|
let that = this;
|
||||||
|
let loop = {
|
||||||
|
open() {
|
||||||
|
if (!this.isOn()) {
|
||||||
|
// 切换为kl_loop
|
||||||
|
that.curPolling.close();
|
||||||
|
that.curPolling = loop;
|
||||||
|
kl();
|
||||||
|
id = setInterval(
|
||||||
|
(() => {
|
||||||
|
if (
|
||||||
|
// 不在线或者意外报错就停掉
|
||||||
|
publicStore().isErr || !that.online
|
||||||
|
) {
|
||||||
|
this.close();
|
||||||
|
} else {
|
||||||
|
kl();
|
||||||
|
}
|
||||||
|
}) as TimerHandler,
|
||||||
|
60_000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
if (this.isOn()) {
|
||||||
|
clearInterval(id);
|
||||||
|
id = -1;
|
||||||
|
// 重置为默认的nullloop
|
||||||
|
that.curPolling = nullLoop;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isOn() {
|
||||||
|
return id !== -1;
|
||||||
|
},
|
||||||
|
invoke() {},
|
||||||
|
};
|
||||||
|
// 会先运行一次,当有任务执行
|
||||||
|
loop.open();
|
||||||
|
return loop;
|
||||||
|
},
|
||||||
initSession() {
|
initSession() {
|
||||||
return this.baseSubmit(interpret(permachine), {
|
let p1 = this.baseSubmit(interpret(permachine), {
|
||||||
action: "init_session",
|
action: "init_session",
|
||||||
|
}).then((res) => {
|
||||||
|
// 自动调度,维持session活性
|
||||||
|
this.keepaliveSession();
|
||||||
});
|
});
|
||||||
|
return p1
|
||||||
},
|
},
|
||||||
asyncInit() {
|
asyncInit() {
|
||||||
if (!this.online) {
|
if (!this.online) {
|
||||||
@ -263,5 +346,11 @@ export const fetchStore = defineStore("fetch", {
|
|||||||
}
|
}
|
||||||
return Promise.resolve("alrealy init");
|
return Promise.resolve("alrealy init");
|
||||||
},
|
},
|
||||||
|
closeSession() {
|
||||||
|
return this.baseSubmit(interpret(permachine), {
|
||||||
|
action: "close_session",
|
||||||
|
sessionId: undefined,
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user