Skip to content

Commit 119955f

Browse files
perf: Third-Party Token Refresh Optimization in Assistant
1 parent 4135aa3 commit 119955f

File tree

2 files changed

+101
-27
lines changed

2 files changed

+101
-27
lines changed

frontend/src/stores/assistant.ts

Lines changed: 99 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const flagKey = 'sqlbit-assistant-flag'
88
type Resolver<T = any> = (value: T | PromiseLike<T>) => void
99
type Rejecter = (reason?: any) => void
1010
interface PendingRequest<T = any> {
11+
requestId: string
1112
resolve: Resolver<T>
1213
reject: Rejecter
1314
}
@@ -23,7 +24,9 @@ interface AssistantState {
2324
history: boolean
2425
hostOrigin: string
2526
autoDs?: boolean
26-
requestPromiseMap: Map<string, PendingRequest>
27+
requestPromiseMap: Map<string, PendingRequest[]>
28+
pedding: boolean
29+
certificateTime: number
2730
}
2831

2932
export const AssistantStore = defineStore('assistant', {
@@ -40,7 +43,9 @@ export const AssistantStore = defineStore('assistant', {
4043
history: true,
4144
hostOrigin: '',
4245
autoDs: false,
43-
requestPromiseMap: new Map<string, PendingRequest>(),
46+
requestPromiseMap: new Map<string, PendingRequest[]>(),
47+
pedding: false,
48+
certificateTime: 0,
4449
}
4550
},
4651
getters: {
@@ -82,45 +87,114 @@ export const AssistantStore = defineStore('assistant', {
8287
},
8388
},
8489
actions: {
85-
refreshCertificate<T>() {
86-
const timeout = 30000
87-
return new Promise((resolve, reject) => {
88-
const timeoutId = setTimeout(() => {
89-
this.requestPromiseMap.delete(this.id)
90-
reject(new Error(`Request ${this.id} timed out after ${timeout}ms`))
91-
}, timeout)
92-
this.requestPromiseMap.set(this.id, {
90+
refreshCertificate<T>(requestUrl?: string) {
91+
if (+new Date() > this.certificateTime + 5000) {
92+
return
93+
}
94+
const timeout = 5000
95+
let peddingList = this.requestPromiseMap.get(this.id)
96+
if (!peddingList) {
97+
this.requestPromiseMap.set(this.id, [])
98+
peddingList = this.requestPromiseMap.get(this.id)
99+
}
100+
101+
const removeRequest = (requestId: string) => {
102+
if (!peddingList) return
103+
let len = peddingList.length
104+
while (len--) {
105+
const peddingRequest = peddingList[len]
106+
if (peddingRequest?.requestId === requestId) {
107+
peddingList.splice(len, 1)
108+
}
109+
}
110+
}
111+
112+
const addRequest = (requestId: string, resolve: any, reject: any) => {
113+
const currentPeddingRequest = {
114+
requestId,
93115
resolve: (value: T) => {
94-
clearTimeout(timeoutId)
95-
this.requestPromiseMap.delete(this.id)
116+
removeRequest(requestId)
96117
resolve(value)
97118
},
98-
reject: (reason) => {
99-
clearTimeout(timeoutId)
100-
this.requestPromiseMap.delete(this.id)
119+
reject: (reason: any) => {
120+
removeRequest(requestId)
101121
reject(reason)
102122
},
103-
})
104-
const readyData = {
105-
eventName: this.pageEmbedded ? 'sqlbot_embedded_event' : 'sqlbot_assistant_event',
106-
busi: 'ready',
107-
ready: true,
108-
messageId: this.id,
123+
} as PendingRequest
124+
peddingList?.push(currentPeddingRequest)
125+
}
126+
127+
return new Promise((resolve, reject) => {
128+
const currentRequestId = `${this.id}|${+new Date()}`
129+
const timeoutId = setTimeout(() => {
130+
removeRequest(currentRequestId)
131+
console.error(`Request ${currentRequestId}[${requestUrl}] timed out after ${timeout}ms`)
132+
resolve(null)
133+
if (timeoutId) {
134+
clearTimeout(timeoutId)
135+
}
136+
// reject(new Error(`Request ${this.id} timed out after ${timeout}ms`))
137+
}, timeout)
138+
139+
const cleanupAndResolve = (value: any) => {
140+
if (timeoutId) {
141+
clearTimeout(timeoutId)
142+
}
143+
resolve(value)
144+
}
145+
146+
const cleanupAndReject = (reason: any) => {
147+
if (timeoutId) {
148+
clearTimeout(timeoutId)
149+
}
150+
reject(reason)
151+
}
152+
153+
addRequest(currentRequestId, cleanupAndResolve, cleanupAndReject)
154+
if (!this.pedding) {
155+
const readyData = {
156+
eventName: this.pageEmbedded ? 'sqlbot_embedded_event' : 'sqlbot_assistant_event',
157+
busi: 'ready',
158+
ready: true,
159+
messageId: this.id,
160+
}
161+
window.parent.postMessage(readyData, '*')
162+
this.pedding = true
109163
}
110-
window.parent.postMessage(readyData, '*')
111164
})
112165
},
113166
resolveCertificate(data?: any) {
114-
const peddingRequest = this.requestPromiseMap.get(this.id)
115-
if (peddingRequest) {
116-
peddingRequest.resolve(data)
167+
const peddingRequestList = this.requestPromiseMap.get(this.id)
168+
if (peddingRequestList?.length) {
169+
peddingRequestList.forEach((peddingRequest: PendingRequest) => {
170+
peddingRequest.resolve(data)
171+
})
117172
}
173+
this.pedding = false
174+
/* const resolvePromiseList = [] as Promise<void>[]
175+
if (peddingRequestList?.length) {
176+
peddingRequestList.forEach((peddingRequest: PendingRequest) => {
177+
const resolvePromise = new Promise((r: any) => {
178+
peddingRequest.resolve(data)
179+
r()
180+
})
181+
resolvePromiseList.push(resolvePromise as Promise<void>)
182+
})
183+
}
184+
if (resolvePromiseList?.length) {
185+
Promise.all(resolvePromiseList).then(() => {
186+
this.pedding = false
187+
})
188+
} else {
189+
this.pedding = false
190+
} */
118191
},
119192
setId(id: string) {
120193
this.id = id
121194
},
122195
setCertificate(certificate: string) {
123196
this.certificate = certificate
197+
this.certificateTime = +new Date()
124198
},
125199
setType(type: number) {
126200
this.type = type

frontend/src/utils/request.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class HttpService {
112112
/^\/chat/.test(config.url || '') ||
113113
config.url?.includes('/system/assistant/ds')
114114
) {
115-
await assistantStore.refreshCertificate()
115+
await assistantStore.refreshCertificate(config.url || '')
116116
}
117117
config.headers['X-SQLBOT-ASSISTANT-CERTIFICATE'] = btoa(
118118
encodeURIComponent(assistantStore.getCertificate)
@@ -321,7 +321,7 @@ class HttpService {
321321
!!(assistantStore.getType % 2) &&
322322
assistantStore.getCertificate
323323
) {
324-
await assistantStore.refreshCertificate()
324+
await assistantStore.refreshCertificate(url)
325325
heads['X-SQLBOT-ASSISTANT-CERTIFICATE'] = btoa(
326326
encodeURIComponent(assistantStore.getCertificate)
327327
)

0 commit comments

Comments
 (0)