Skip to content

Commit 3b76085

Browse files
committed
1 parent 2295b67 commit 3b76085

3 files changed

Lines changed: 46 additions & 17 deletions

File tree

extensions/git/src/autofetch.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@
55

66
'use strict';
77

8-
import { workspace, Disposable } from 'vscode';
8+
import { workspace, Disposable, EventEmitter } from 'vscode';
99
import { GitErrorCodes } from './git';
1010
import { Repository } from './repository';
11-
import { throttle } from './decorators';
11+
import { eventToPromise, filterEvent } from './util';
1212

1313
export class AutoFetcher {
1414

1515
private static Period = 3 * 60 * 1000 /* three minutes */;
16+
17+
private _onDidChange = new EventEmitter<boolean>();
18+
private onDidChange = this._onDidChange.event;
19+
20+
private _enabled: boolean = false;
21+
get enabled(): boolean { return this._enabled; }
22+
set enabled(enabled: boolean) { this._enabled = enabled; this._onDidChange.fire(enabled); }
23+
1624
private disposables: Disposable[] = [];
17-
private timer: NodeJS.Timer;
1825

1926
constructor(private repository: Repository) {
2027
workspace.onDidChangeConfiguration(this.onConfiguration, this, this.disposables);
@@ -32,26 +39,41 @@ export class AutoFetcher {
3239
}
3340

3441
enable(): void {
35-
if (this.timer) {
42+
if (this.enabled) {
3643
return;
3744
}
3845

39-
this.fetch();
40-
this.timer = setInterval(() => this.fetch(), AutoFetcher.Period);
46+
this.enabled = true;
47+
this.run();
4148
}
4249

4350
disable(): void {
44-
clearInterval(this.timer);
51+
this.enabled = false;
4552
}
4653

47-
@throttle
48-
private async fetch(): Promise<void> {
49-
try {
50-
await this.repository.fetch();
51-
} catch (err) {
52-
if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) {
53-
this.disable();
54+
private async run(): Promise<void> {
55+
while (this.enabled) {
56+
await this.repository.whenIdleAndFocused();
57+
58+
if (!this.enabled) {
59+
return;
5460
}
61+
62+
try {
63+
await this.repository.fetch();
64+
} catch (err) {
65+
if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) {
66+
this.disable();
67+
}
68+
}
69+
70+
if (!this.enabled) {
71+
return;
72+
}
73+
74+
const timeout = new Promise(c => setTimeout(c, AutoFetcher.Period));
75+
const whenDisabled = eventToPromise(filterEvent(this.onDidChange, enabled => !enabled));
76+
await Promise.race([timeout, whenDisabled]);
5577
}
5678
}
5779

extensions/git/src/contentProvider.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
'use strict';
77

88
import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode';
9-
import { debounce } from './decorators';
9+
import { debounce, throttle } from './decorators';
1010
import { fromGitUri } from './uri';
1111
import { Model, ModelChangeEvent } from './model';
12+
import { filterEvent, eventToPromise } from './util';
1213

1314
interface CacheRow {
1415
uri: Uri;
@@ -50,7 +51,13 @@ export class GitContentProvider {
5051
this.fireChangeEvents();
5152
}
5253

53-
private fireChangeEvents(): void {
54+
@throttle
55+
private async fireChangeEvents(): Promise<void> {
56+
if (!window.state.focused) {
57+
const onDidFocusWindow = filterEvent(window.onDidChangeWindowState, e => e.focused);
58+
await eventToPromise(onDidFocusWindow);
59+
}
60+
5461
Object.keys(this.cache).forEach(key => {
5562
const uri = this.cache[key].uri;
5663
const fsPath = uri.fsPath;

extensions/git/src/repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ export class Repository implements Disposable {
816816
await timeout(5000);
817817
}
818818

819-
private async whenIdleAndFocused(): Promise<void> {
819+
async whenIdleAndFocused(): Promise<void> {
820820
while (true) {
821821
if (!this.operations.isIdle()) {
822822
await eventToPromise(this.onDidRunOperation);

0 commit comments

Comments
 (0)