⚡ perf(vscode): 预览发文档后在后台问语言扩展的请求排队发:同时在途最多 4 个、离视口近的先问、文档改了排着的作废,看得见的中文名先交
This commit is contained in:
1 parent
5a0c5490ea
commit
12ad047b4d
7 files changed
+335
-45
No files matched your search
@@ -46,7 +46,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
},
|
||||
}
|
||||
const posted: { type: string, counts?: Record<string, number> }[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(posted).toEqual([{ type: 'callTreeCounts', version: 3, counts: { fn: 1, inner: 1 } }])
|
||||
@@ -71,7 +71,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
version = 2
|
||||
session.documentSent()
|
||||
@@ -91,7 +91,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
load: async () => ({ symbol: mask, edges: [edge] }),
|
||||
}
|
||||
const posted: { type: string, version?: number, anchor?: string, trees?: { name: string }[] }[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.open(3, 'fn')
|
||||
expect(posted).toEqual([])
|
||||
session.documentSent()
|
||||
@@ -124,7 +124,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(posted).toEqual([{ type: 'callTreeCounts', version: 5, counts: {} }])
|
||||
@@ -158,7 +158,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
load: async () => ({ symbol: symbol('nobody'), edges: [] }),
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
posted.length = 0
|
||||
@@ -187,7 +187,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
session.open(7, 'fn')
|
||||
version = 8
|
||||
@@ -210,7 +210,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(asked).toEqual([endpoint])
|
||||
@@ -231,7 +231,7 @@ describe('调用树棵数在文档发出去之后算', () => {
|
||||
load: async () => ({ symbol: route, edges: callers, contractMiss: { files: ['web/src/lib/api/schema.d.ts'] } }),
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(posted).toEqual([{ type: 'callTreeCounts', version: 10, counts: {} }])
|
||||
@@ -277,7 +277,7 @@ describe('同一版文档又发一遍(页面重新加载、按新规则重发
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(asked).toEqual(['fn', 'alone', 'unknown'])
|
||||
@@ -314,7 +314,7 @@ describe('同一版文档又发一遍(页面重新加载、按新规则重发
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(posted).toEqual([])
|
||||
@@ -346,7 +346,7 @@ describe('同一版文档又发一遍(页面重新加载、按新规则重发
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
posted.length = 0
|
||||
@@ -372,7 +372,7 @@ describe('同一版文档又发一遍(页面重新加载、按新规则重发
|
||||
},
|
||||
}
|
||||
const posted: unknown[] = []
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source)
|
||||
const session = new CallTreeSession(message => posted.push(message), () => source, () => 0)
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
source.blocks = [route('/api/v1/agents'), block('fn', 'function', 1)]
|
||||
@@ -388,6 +388,24 @@ describe('同一版文档又发一遍(页面重新加载、按新规则重发
|
||||
})
|
||||
})
|
||||
|
||||
describe('后台数的顺序', () => {
|
||||
it('离视口近的块先问', async () => {
|
||||
const asked: number[] = []
|
||||
const source: CallTreeSource = {
|
||||
version: 1,
|
||||
blocks: [block('a', 'function', 10), block('b', 'function', 500), block('c', 'class', 300)],
|
||||
load: async ({ defines }) => {
|
||||
asked.push(defines?.startIndex ?? -1)
|
||||
return { symbol: symbol('nobody'), edges: [] }
|
||||
},
|
||||
}
|
||||
const session = new CallTreeSession(() => {}, () => source, offset => Math.abs(offset - 320))
|
||||
session.documentSent()
|
||||
await viFlush()
|
||||
expect(asked).toEqual([300, 500, 10])
|
||||
})
|
||||
})
|
||||
|
||||
async function viFlush(): Promise<void> {
|
||||
await new Promise(resolve => setTimeout(resolve, 0))
|
||||
await new Promise(resolve => setTimeout(resolve, 0))
|
||||
|
||||
@@ -58,6 +58,8 @@ export class CallTreeSession {
|
||||
constructor(
|
||||
private readonly post: (message: ExtensionToWebview) => void,
|
||||
private readonly source: () => CallTreeSource | undefined,
|
||||
/** 名字起点在 offset 的块离页面视口多远:后台先数近的 */
|
||||
private readonly distance: (offset: number) => number,
|
||||
) {}
|
||||
|
||||
/** 文档发出去了:还是手上这一版就接着用,换了一版就从头数。 */
|
||||
@@ -104,7 +106,10 @@ export class CallTreeSession {
|
||||
void this.scan(version)
|
||||
}
|
||||
|
||||
/** 一块一块问还没问过的,每问完一块按眼下发出去的块树再找下一块(数的时候文档可能又按同一版重发了);问了才在数完时发棵数。 */
|
||||
/**
|
||||
* 一块一块问还没问过的,先问离视口近的;每问完一块按眼下发出去的块树、眼下的视口再挑下一块(数的时候文档可能又按同一版重发了、页面可能滚了)。
|
||||
* 问了才在数完时发棵数。
|
||||
*/
|
||||
private async scan(version: number): Promise<void> {
|
||||
this.scanning = version
|
||||
let asked = false
|
||||
@@ -113,7 +118,11 @@ export class CallTreeSession {
|
||||
const src = this.source()
|
||||
if (!src || this.stale(version))
|
||||
return
|
||||
const next = callBlocks(src.blocks).find(block => !this.answerOf(block))
|
||||
let next: NamedCallBlock | undefined
|
||||
for (const block of callBlocks(src.blocks)) {
|
||||
if (!this.answerOf(block) && (!next || this.distance(block.defines.startIndex) < this.distance(next.defines.startIndex)))
|
||||
next = block
|
||||
}
|
||||
if (!next)
|
||||
break
|
||||
asked = true
|
||||
@@ -199,11 +208,11 @@ export class CallTreeSession {
|
||||
}
|
||||
|
||||
/** 宿主标了能看调用树(callTree)、有名字起点的块,含嵌在别的块里面的。 */
|
||||
function callBlocks(blocks: readonly CallTreeBlock[]): CallTreeBlock[] {
|
||||
const found: CallTreeBlock[] = []
|
||||
function callBlocks(blocks: readonly CallTreeBlock[]): NamedCallBlock[] {
|
||||
const found: NamedCallBlock[] = []
|
||||
const walk = (list: readonly CallTreeBlock[]) => {
|
||||
for (const block of list) {
|
||||
if (block.callTree && block.defines)
|
||||
if (isNamedCallBlock(block))
|
||||
found.push(block)
|
||||
if (block.children?.length)
|
||||
walk(block.children)
|
||||
@@ -213,6 +222,13 @@ function callBlocks(blocks: readonly CallTreeBlock[]): CallTreeBlock[] {
|
||||
return found
|
||||
}
|
||||
|
||||
/** 能看调用树、有名字起点的块。 */
|
||||
type NamedCallBlock = CallTreeBlock & Required<Pick<CallTreeBlock, 'defines'>>
|
||||
|
||||
function isNamedCallBlock(block: CallTreeBlock): block is NamedCallBlock {
|
||||
return !!block.callTree && !!block.defines
|
||||
}
|
||||
|
||||
/** 一块怎么问:名字起点和接口。同一版文档按新规则重发时接口可能变了(查到了挂载前缀),变了就得重问。 */
|
||||
function targetOf(block: CallTreeBlock): string {
|
||||
return JSON.stringify([block.defines?.startIndex, block.callTree?.endpoint])
|
||||
|
||||
Reference in new issue
Block a user