use Mutex for rename files in sequence
This commit is contained in:
parent
8fb49605c7
commit
8fadbb20d7
2 changed files with 64 additions and 4 deletions
|
@ -9,6 +9,7 @@ import * as Proto from '../protocol'
|
|||
import { ITypeScriptServiceClient } from '../typescriptService'
|
||||
import * as typeConverters from '../utils/typeConverters'
|
||||
import FileConfigurationManager from './fileConfigurationManager'
|
||||
import { Mutex } from '../utils/mutex'
|
||||
|
||||
function wait(ms: number): Promise<any> {
|
||||
return new Promise(resolve => {
|
||||
|
@ -29,10 +30,16 @@ export default class UpdateImportsOnFileRenameHandler {
|
|||
let glob = languageId == 'typescript' ? '**/*.{ts,tsx}' : '**/*.{js,jsx}'
|
||||
const watcher = workspace.createFileSystemWatcher(glob)
|
||||
this.disposables.push(watcher)
|
||||
watcher.onDidRename(e => {
|
||||
this.doRename(e.oldUri, e.newUri).catch(e => {
|
||||
client.logger.error(e.message)
|
||||
})
|
||||
let mutex = new Mutex()
|
||||
watcher.onDidRename(async e => {
|
||||
let release = await mutex.acquire()
|
||||
try {
|
||||
await this.doRename(e.oldUri, e.newUri)
|
||||
release()
|
||||
} catch (e) {
|
||||
this.client.logger.error('Error on rename:', e)
|
||||
release()
|
||||
}
|
||||
}, null, this.disposables)
|
||||
}
|
||||
|
||||
|
@ -50,6 +57,10 @@ export default class UpdateImportsOnFileRenameHandler {
|
|||
const targetFile = newResource.fsPath
|
||||
const oldFile = oldResource.fsPath
|
||||
const newUri = newResource.toString()
|
||||
let oldDocument = workspace.getDocument(oldResource.toString())
|
||||
if (oldDocument) {
|
||||
await workspace.nvim.command(`silent ${oldDocument.bufnr}bwipeout!`)
|
||||
}
|
||||
let document = workspace.getDocument(newUri)
|
||||
if (document) {
|
||||
await workspace.nvim.command(`silent ${document.bufnr}bwipeout!`)
|
||||
|
|
49
src/server/utils/mutex.ts
Normal file
49
src/server/utils/mutex.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
export class Mutex {
|
||||
private tasks: (() => void)[] = []
|
||||
private count = 1
|
||||
|
||||
private sched(): void {
|
||||
if (this.count > 0 && this.tasks.length > 0) {
|
||||
this.count--
|
||||
let next = this.tasks.shift()
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
public get busy(): boolean {
|
||||
return this.count == 0
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: typedef
|
||||
public acquire() {
|
||||
return new Promise<() => void>(res => {
|
||||
let task = () => {
|
||||
let released = false
|
||||
res(() => {
|
||||
if (!released) {
|
||||
released = true
|
||||
this.count++
|
||||
this.sched()
|
||||
}
|
||||
})
|
||||
}
|
||||
this.tasks.push(task)
|
||||
process.nextTick(this.sched.bind(this))
|
||||
})
|
||||
}
|
||||
|
||||
public use<T>(f: () => Promise<T>): Promise<T> {
|
||||
return this.acquire()
|
||||
.then(release => {
|
||||
return f()
|
||||
.then(res => {
|
||||
release()
|
||||
return res
|
||||
})
|
||||
.catch(err => {
|
||||
release()
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue