🐛 fix(vscode): webhook 窗口登记先写临时文件再改名,避免被占端口的窗口当成陈旧条目删掉
This commit is contained in:
1 parent
2dabbf1200
commit
3e3de0ae07
2 files changed
+27
-2
No files matched your search
@@ -36,9 +36,13 @@ function processAlive(pid: number): boolean {
|
||||
export class PeerRegistry {
|
||||
constructor(private readonly dir: string) {}
|
||||
|
||||
/** 先写进临时文件再改名成端口号,别的窗口列登记时就不会读到还没写进 pid 的空文件、把它当成已退出的窗口删掉。 */
|
||||
async add(port: number): Promise<void> {
|
||||
await fsp.mkdir(this.dir, { recursive: true })
|
||||
await fsp.writeFile(path.join(this.dir, String(port)), String(process.pid))
|
||||
const file = path.join(this.dir, String(port))
|
||||
const temp = `${file}.${process.pid}.tmp`
|
||||
await fsp.writeFile(temp, String(process.pid))
|
||||
await fsp.rename(temp, file)
|
||||
}
|
||||
|
||||
async remove(port: number): Promise<void> {
|
||||
|
||||
@@ -2,10 +2,11 @@ import type { IncomingHttpHeaders } from 'node:http'
|
||||
import type { WebhookEvent } from './eventParser'
|
||||
import { Buffer } from 'node:buffer'
|
||||
import { createHmac } from 'node:crypto'
|
||||
import { mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { promises as fsp, mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { PeerRegistry } from './relay'
|
||||
import { handleWebhookRequest, WebhookServer } from './server'
|
||||
|
||||
const mocks = vi.hoisted(() => ({ log: vi.fn() }))
|
||||
@@ -206,6 +207,26 @@ describe('同一台机器多个窗口共用端口', () => {
|
||||
await vi.waitFor(() => expect(readdirSync(dir)).toEqual([]))
|
||||
})
|
||||
|
||||
it('登记文件写到一半时别的窗口来列登记,不会把它当成陈旧条目删掉', async () => {
|
||||
const registry = new PeerRegistry(path.join(peerRoot, '17421'))
|
||||
const remove = vi.spyOn(registry, 'remove')
|
||||
const realWriteFile = fsp.writeFile.bind(fsp)
|
||||
const write = vi.spyOn(fsp, 'writeFile').mockImplementation(async (file, data) => {
|
||||
// 文件已经建好、pid 还没写进去的那一刻,占着端口的窗口正好来列登记。
|
||||
await realWriteFile(file, '')
|
||||
await registry.ports()
|
||||
await realWriteFile(file, data)
|
||||
})
|
||||
try {
|
||||
await registry.add(50000)
|
||||
}
|
||||
finally {
|
||||
write.mockRestore()
|
||||
}
|
||||
expect(remove).not.toHaveBeenCalled()
|
||||
expect(await registry.ports()).toEqual([50000])
|
||||
})
|
||||
|
||||
it('同一端口重复 start 不会自己挤掉自己', async () => {
|
||||
const hub = open()
|
||||
await hub.server.start(0)
|
||||
|
||||
Reference in new issue
Block a user