Skip to content

Commit 7024e62

Browse files
author
Benjamin Pasero
committed
perf - init state service async on startup
1 parent 01659db commit 7024e62

4 files changed

Lines changed: 72 additions & 35 deletions

File tree

src/vs/code/electron-main/app.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
6363
import { hasArgs } from 'vs/platform/environment/node/argv';
6464
import { RunOnceScheduler } from 'vs/base/common/async';
6565
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
66-
import { THEME_STORAGE_KEY, THEME_BG_STORAGE_KEY } from 'vs/code/electron-main/theme';
66+
import { storeBackgroundColor } from 'vs/code/electron-main/theme';
6767
import { nativeSep, join } from 'vs/base/common/paths';
6868
import { homedir } from 'os';
6969
import { localize } from 'vs/nls';
@@ -283,10 +283,7 @@ export class CodeApplication extends Disposable {
283283

284284
// Theme changes
285285
if (event === 'vscode:changeColorTheme' && typeof payload === 'string') {
286-
let data = JSON.parse(payload);
287-
288-
this.stateService.setItem(THEME_STORAGE_KEY, data.baseTheme);
289-
this.stateService.setItem(THEME_BG_STORAGE_KEY, data.background);
286+
storeBackgroundColor(this.stateService, JSON.parse(payload));
290287
}
291288
}
292289

src/vs/code/electron-main/main.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,26 @@ async function cleanupOlderLogs(environmentService: EnvironmentService): Promise
6363
await Promise.all(toDelete.map(name => rimraf(path.join(logsRoot, name))));
6464
}
6565

66-
function createPaths(environmentService: IEnvironmentService): Promise<any> {
67-
const paths = [
66+
function initServices(environmentService: IEnvironmentService, stateService: StateService): Promise<any> {
67+
68+
// Ensure paths for environment service exist
69+
const environmentServiceInitialization = Promise.all([
6870
environmentService.extensionsPath,
6971
environmentService.nodeCachedDataDir,
7072
environmentService.logsPath,
7173
environmentService.globalStorageHome,
7274
environmentService.workspaceStorageHome,
7375
environmentService.backupHome
74-
];
76+
].map(path => path && mkdirp(path)));
77+
78+
// State service
79+
const stateServiceInitialization = stateService.init();
7580

76-
return Promise.all(paths.map(path => path && mkdirp(path)));
81+
return Promise.all([environmentServiceInitialization, stateServiceInitialization]);
7782
}
7883

7984
class ExpectedError extends Error {
80-
public readonly isExpected = true;
85+
readonly isExpected = true;
8186
}
8287

8388
function setupIPC(accessor: ServicesAccessor): Promise<Server> {
@@ -310,12 +315,13 @@ function startup(args: ParsedArgs): void {
310315
const instantiationService = createServices(args, bufferLogService);
311316
instantiationService.invokeFunction(accessor => {
312317
const environmentService = accessor.get(IEnvironmentService);
318+
const stateService = accessor.get(IStateService);
313319

314320
// Patch `process.env` with the instance's environment
315321
const instanceEnvironment = patchEnvironment(environmentService);
316322

317323
// Startup
318-
return createPaths(environmentService)
324+
return initServices(environmentService, stateService as StateService)
319325
.then(() => instantiationService.invokeFunction(setupIPC), error => {
320326

321327
// Show a dialog for errors that can be resolved by the user

src/vs/code/electron-main/theme.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ import { isWindows, isMacintosh } from 'vs/base/common/platform';
77
import { systemPreferences } from 'electron';
88
import { IStateService } from 'vs/platform/state/common/state';
99

10-
export const DEFAULT_BG_LIGHT = '#FFFFFF';
11-
export const DEFAULT_BG_DARK = '#1E1E1E';
12-
export const DEFAULT_BG_HC_BLACK = '#000000';
10+
const DEFAULT_BG_LIGHT = '#FFFFFF';
11+
const DEFAULT_BG_DARK = '#1E1E1E';
12+
const DEFAULT_BG_HC_BLACK = '#000000';
1313

14-
export const THEME_STORAGE_KEY = 'theme';
15-
export const THEME_BG_STORAGE_KEY = 'themeBackground';
14+
const THEME_STORAGE_KEY = 'theme';
15+
const THEME_BG_STORAGE_KEY = 'themeBackground';
16+
17+
export function storeBackgroundColor(stateService: IStateService, data: { baseTheme: string, background: string }): void {
18+
stateService.setItem(THEME_STORAGE_KEY, data.baseTheme);
19+
stateService.setItem(THEME_BG_STORAGE_KEY, data.background);
20+
}
1621

1722
export function getBackgroundColor(stateService: IStateService): string {
1823
if (isWindows && systemPreferences.isInvertedColorScheme()) {

src/vs/platform/state/node/stateService.ts

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,48 @@ import { writeFileAndFlushSync } from 'vs/base/node/extfs';
1010
import { isUndefined, isUndefinedOrNull } from 'vs/base/common/types';
1111
import { IStateService } from 'vs/platform/state/common/state';
1212
import { ILogService } from 'vs/platform/log/common/log';
13+
import { readFile } from 'vs/base/node/pfs';
1314

1415
export class FileStorage {
1516

16-
private _lazyDatabase: object | null = null;
17+
private _database: object | null = null;
1718

18-
constructor(private dbPath: string, private onError: (error) => void) { }
19+
constructor(private dbPath: string, private onError: (error: Error) => void) { }
1920

2021
private get database(): object {
21-
if (!this._lazyDatabase) {
22-
this._lazyDatabase = this.loadSync();
22+
if (!this._database) {
23+
this._database = this.loadSync();
24+
}
25+
26+
return this._database;
27+
}
28+
29+
init(): Promise<void> {
30+
return readFile(this.dbPath).then(contents => {
31+
try {
32+
this._database = JSON.parse(contents.toString());
33+
} catch (error) {
34+
this._database = {};
35+
}
36+
}, error => {
37+
if (error.code !== 'ENOENT') {
38+
this.onError(error);
39+
}
40+
41+
this._database = {};
42+
});
43+
}
44+
45+
private loadSync(): object {
46+
try {
47+
return JSON.parse(fs.readFileSync(this.dbPath).toString());
48+
} catch (error) {
49+
if (error.code !== 'ENOENT') {
50+
this.onError(error);
51+
}
52+
53+
return {};
2354
}
24-
return this._lazyDatabase;
2555
}
2656

2757
getItem<T>(key: string, defaultValue: T): T;
@@ -36,6 +66,7 @@ export class FileStorage {
3666
}
3767

3868
setItem(key: string, data: any): void {
69+
3970
// Remove an item when it is undefined or null
4071
if (isUndefinedOrNull(data)) {
4172
return this.removeItem(key);
@@ -53,25 +84,14 @@ export class FileStorage {
5384
}
5485

5586
removeItem(key: string): void {
87+
5688
// Only update if the key is actually present (not undefined)
5789
if (!isUndefined(this.database[key])) {
5890
this.database[key] = void 0;
5991
this.saveSync();
6092
}
6193
}
6294

63-
private loadSync(): object {
64-
try {
65-
return JSON.parse(fs.readFileSync(this.dbPath).toString()); // invalid JSON or permission issue can happen here
66-
} catch (error) {
67-
if (error && error.code !== 'ENOENT') {
68-
this.onError(error);
69-
}
70-
71-
return {};
72-
}
73-
}
74-
7595
private saveSync(): void {
7696
try {
7797
writeFileAndFlushSync(this.dbPath, JSON.stringify(this.database, null, 4)); // permission issue can happen here
@@ -85,10 +105,19 @@ export class StateService implements IStateService {
85105

86106
_serviceBrand: any;
87107

108+
private static STATE_FILE = 'storage.json';
109+
88110
private fileStorage: FileStorage;
89111

90-
constructor(@IEnvironmentService environmentService: IEnvironmentService, @ILogService logService: ILogService) {
91-
this.fileStorage = new FileStorage(path.join(environmentService.userDataPath, 'storage.json'), error => logService.error(error));
112+
constructor(
113+
@IEnvironmentService environmentService: IEnvironmentService,
114+
@ILogService logService: ILogService
115+
) {
116+
this.fileStorage = new FileStorage(path.join(environmentService.userDataPath, StateService.STATE_FILE), error => logService.error(error));
117+
}
118+
119+
init(): Promise<void> {
120+
return this.fileStorage.init();
92121
}
93122

94123
getItem<T>(key: string, defaultValue: T): T;

0 commit comments

Comments
 (0)