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 { ITypeScriptServiceClient } from '../typescriptService'
|
||||||
import * as typeConverters from '../utils/typeConverters'
|
import * as typeConverters from '../utils/typeConverters'
|
||||||
import FileConfigurationManager from './fileConfigurationManager'
|
import FileConfigurationManager from './fileConfigurationManager'
|
||||||
|
import { Mutex } from '../utils/mutex'
|
||||||
|
|
||||||
function wait(ms: number): Promise<any> {
|
function wait(ms: number): Promise<any> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
@ -29,10 +30,16 @@ export default class UpdateImportsOnFileRenameHandler {
|
||||||
let glob = languageId == 'typescript' ? '**/*.{ts,tsx}' : '**/*.{js,jsx}'
|
let glob = languageId == 'typescript' ? '**/*.{ts,tsx}' : '**/*.{js,jsx}'
|
||||||
const watcher = workspace.createFileSystemWatcher(glob)
|
const watcher = workspace.createFileSystemWatcher(glob)
|
||||||
this.disposables.push(watcher)
|
this.disposables.push(watcher)
|
||||||
watcher.onDidRename(e => {
|
let mutex = new Mutex()
|
||||||
this.doRename(e.oldUri, e.newUri).catch(e => {
|
watcher.onDidRename(async e => {
|
||||||
client.logger.error(e.message)
|
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)
|
}, null, this.disposables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +57,10 @@ export default class UpdateImportsOnFileRenameHandler {
|
||||||
const targetFile = newResource.fsPath
|
const targetFile = newResource.fsPath
|
||||||
const oldFile = oldResource.fsPath
|
const oldFile = oldResource.fsPath
|
||||||
const newUri = newResource.toString()
|
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)
|
let document = workspace.getDocument(newUri)
|
||||||
if (document) {
|
if (document) {
|
||||||
await workspace.nvim.command(`silent ${document.bufnr}bwipeout!`)
|
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