提交 593e1787 编写于 作者: B Benjamin Pasero

sandbox - make timer service available in electron-sandbox

cc @jrieken
上级 add7bbfa
......@@ -309,3 +309,22 @@ export interface CrashReporterStartOptions {
*/
globalExtra?: Record<string, string>;
}
export interface ProcessMemoryInfo {
/**
* The amount of memory not shared by other processes, such as JS heap or HTML
* content in Kilobytes.
*/
private: number;
/**
* The amount of memory currently pinned to actual physical RAM in Kilobytes.
*
* @platform linux,win32
*/
residentSet: number;
/**
* The amount of memory shared between processes, typically memory consumed by the
* Electron code itself in Kilobytes.
*/
shared: number;
}
......@@ -94,6 +94,7 @@
platform: process.platform,
env: process.env,
versions: process.versions,
_whenEnvResolved: undefined,
get whenEnvResolved() {
if (!this._whenEnvResolved) {
......@@ -102,6 +103,15 @@
return this._whenEnvResolved;
},
getProcessMemoryInfo:
/**
* @returns {Promise<import('electron').ProcessMemoryInfo>}
*/
function () {
return process.getProcessMemoryInfo();
},
on:
/**
* @param {string} type
......
......@@ -3,6 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ProcessMemoryInfo } from 'vs/base/parts/sandbox/common/electronTypes';
export const ipcRenderer = (window as any).vscode.ipcRenderer as {
/**
......@@ -95,6 +97,21 @@ export const process = (window as any).vscode.process as {
*/
on: (type: string, callback: Function) => void;
/**
* Resolves with a ProcessMemoryInfo
*
* Returns an object giving memory usage statistics about the current process. Note
* that all statistics are reported in Kilobytes. This api should be called after
* app ready.
*
* Chromium does not provide `residentSet` value for macOS. This is because macOS
* performs in-memory compression of pages that haven't been recently used. As a
* result the resident set size value is not what one would expect. `private`
* memory is more representative of the actual pre-compression memory usage of the
* process on macOS.
*/
getProcessMemoryInfo: () => ProcessMemoryInfo;
/**
* A list of versions for the current node.js/electron configuration.
*/
......
......@@ -293,13 +293,13 @@ class ProcessExplorer {
container.append(tableHead);
const hasMultipleMachines = Object.keys(processLists).length > 1;
const totalMem = await this.electronService.getTotalMem();
const { totalmem } = await this.electronService.getOSStatistics();
processLists.forEach((remote, i) => {
const isLocal = i === 0;
if (isRemoteDiagnosticError(remote.rootProcess)) {
this.renderProcessFetchError(remote.name, remote.rootProcess.errorMessage);
} else {
this.renderTableSection(remote.name, this.getProcessList(remote.rootProcess, isLocal, totalMem), hasMultipleMachines, isLocal);
this.renderTableSection(remote.name, this.getProcessList(remote.rootProcess, isLocal, totalmem), hasMultipleMachines, isLocal);
}
});
}
......
......@@ -10,11 +10,23 @@ import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { ColorScheme } from 'vs/platform/theme/common/theme';
export interface ICPUProperties {
model: string;
speed: number;
}
export interface IOSProperties {
type: string;
release: string;
arch: string;
platform: string;
cpus: ICPUProperties[];
}
export interface IOSStatistics {
totalmem: number;
freemem: number;
loadavg: number[];
}
export interface ICommonElectronService {
......@@ -82,8 +94,10 @@ export interface ICommonElectronService {
updateTouchBar(items: ISerializableCommandAction[][]): Promise<void>;
moveItemToTrash(fullPath: string, deleteOnFail?: boolean): Promise<boolean>;
isAdmin(): Promise<boolean>;
getTotalMem(): Promise<number>;
getOS(): Promise<IOSProperties>;
getOSProperties(): Promise<IOSProperties>;
getOSStatistics(): Promise<IOSStatistics>;
getOSVirtualMachineHint(): Promise<number>;
// Process
killProcess(pid: number, code: string): Promise<void>;
......
......@@ -11,7 +11,7 @@ import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifec
import { IOpenedWindow, IOpenWindowOptions, IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
import { isMacintosh, isWindows, isRootUser } from 'vs/base/common/platform';
import { ICommonElectronService, IOSProperties } from 'vs/platform/electron/common/electron';
import { ICommonElectronService, IOSProperties, IOSStatistics } from 'vs/platform/electron/common/electron';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { AddFirstParameterToFunctions } from 'vs/base/common/types';
......@@ -21,8 +21,9 @@ import { URI } from 'vs/base/common/uri';
import { ITelemetryData, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes';
import { arch, totalmem, release, platform, type } from 'os';
import { arch, totalmem, release, platform, type, loadavg, freemem, cpus } from 'os';
import { ColorScheme } from 'vs/platform/theme/common/theme';
import { virtualMachineHint } from 'vs/base/node/id';
export interface IElectronMainService extends AddFirstParameterToFunctions<ICommonElectronService, Promise<unknown> /* only methods, not events */, number | undefined /* window ID */> { }
......@@ -334,19 +335,28 @@ export class ElectronMainService implements IElectronMainService {
return isAdmin;
}
async getTotalMem(): Promise<number> {
return totalmem();
async getOSStatistics(): Promise<IOSStatistics> {
return {
totalmem: totalmem(),
freemem: freemem(),
loadavg: loadavg()
};
}
async getOS(): Promise<IOSProperties> {
async getOSProperties(): Promise<IOSProperties> {
return {
arch: arch(),
platform: platform(),
release: release(),
type: type()
type: type(),
cpus: cpus()
};
}
async getOSVirtualMachineHint(): Promise<number> {
return virtualMachineHint.value();
}
//#endregion
......
......@@ -19,7 +19,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import * as files from 'vs/workbench/contrib/files/common/files';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { didUseCachedData } from 'vs/workbench/services/timer/electron-browser/timerService';
import { didUseCachedData } from 'vs/workbench/services/timer/electron-sandbox/timerService';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ITimerService } from 'vs/workbench/services/timer/browser/timerService';
......
......@@ -45,7 +45,6 @@ import { ITunnelProvider, ITunnelService, RemoteTunnel } from 'vs/platform/remot
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { IManualSyncTask, IResourcePreview, ISyncResourceHandle, ISyncTask, IUserDataAutoSyncService, IUserDataSyncService, IUserDataSyncStore, IUserDataSyncStoreManagementService, SyncResource, SyncStatus, UserDataSyncStoreType } from 'vs/platform/userDataSync/common/userDataSync';
import { IUserDataSyncAccount, IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
import { AbstractTimerService, IStartupMetrics, ITimerService, Writeable } from 'vs/workbench/services/timer/browser/timerService';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { ITaskProvider, ITaskService, ITaskSummary, ProblemMatcherRunOptions, Task, TaskFilter, TaskTerminateResponse, WorkspaceFolderTaskResult } from 'vs/workbench/contrib/tasks/common/taskService';
import { Action } from 'vs/base/common/actions';
......@@ -765,20 +764,6 @@ registerSingleton(IUserDataSyncStoreManagementService, SimpleIUserDataSyncStoreM
//#endregion
//#region Timer
class SimpleTimerService extends AbstractTimerService {
protected _isInitialStartup(): boolean { return true; }
protected _didUseCachedData(): boolean { return false; }
protected async _getWindowCount(): Promise<number> { return 1; }
protected async _extendStartupInfo(info: Writeable<IStartupMetrics>): Promise<void> { }
}
registerSingleton(ITimerService, SimpleTimerService);
//#endregion
//#region Task
class SimpleTaskService implements ITaskService {
......
......@@ -212,7 +212,7 @@ class NativeDialogService implements IDialogService {
}
const isSnap = process.platform === 'linux' && process.env.SNAP && process.env.SNAP_REVISION;
const os = await this.electronService.getOS();
const osProps = await this.electronService.getOSProperties();
const detailString = (useAgo: boolean): string => {
return nls.localize('aboutDetail',
......@@ -224,7 +224,7 @@ class NativeDialogService implements IDialogService {
process.versions['chrome'],
process.versions['node'],
process.versions['v8'],
`${os.type} ${os.arch} ${os.release}${isSnap ? ' snap' : ''}`
`${osProps.type} ${osProps.arch} ${osProps.release}${isSnap ? ' snap' : ''}`
);
};
......
......@@ -3,8 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { virtualMachineHint } from 'vs/base/node/id';
import * as os from 'os';
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
......@@ -18,6 +16,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IStartupMetrics, AbstractTimerService, Writeable } from 'vs/workbench/services/timer/browser/timerService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { context, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
export class TimerService extends AbstractTimerService {
......@@ -49,12 +48,18 @@ export class TimerService extends AbstractTimerService {
protected async _extendStartupInfo(info: Writeable<IStartupMetrics>): Promise<void> {
try {
info.totalmem = os.totalmem();
info.freemem = os.freemem();
info.platform = os.platform();
info.release = os.release();
info.arch = os.arch();
info.loadavg = os.loadavg();
const [osProperties, osStatistics, virtualMachineHint] = await Promise.all([
this._electronService.getOSProperties(),
this._electronService.getOSStatistics(),
this._electronService.getOSVirtualMachineHint()
]);
info.totalmem = osStatistics.totalmem;
info.freemem = osStatistics.freemem;
info.platform = osProperties.platform;
info.release = osProperties.release;
info.arch = osProperties.arch;
info.loadavg = osStatistics.loadavg;
const processMemoryInfo = await process.getProcessMemoryInfo();
info.meminfo = {
......@@ -63,9 +68,9 @@ export class TimerService extends AbstractTimerService {
sharedBytes: processMemoryInfo.shared
};
info.isVMLikelyhood = Math.round((virtualMachineHint.value() * 100));
info.isVMLikelyhood = Math.round((virtualMachineHint * 100));
const rawCpus = os.cpus();
const rawCpus = osProperties.cpus;
if (rawCpus && rawCpus.length > 0) {
info.cpus = { count: rawCpus.length, speed: rawCpus[0].speed, model: rawCpus[0].model };
}
......@@ -78,8 +83,12 @@ export class TimerService extends AbstractTimerService {
//#region cached data logic
export function didUseCachedData(): boolean {
// TODO@Ben TODO@Jo need a different way to figure out if cached data was used
if (context.sandbox) {
return true;
}
// We surely don't use cached data when we don't tell the loader to do so
if (!Boolean((<any>global).require.getConfig().nodeCachedData)) {
if (!Boolean((<any>window).require.getConfig().nodeCachedData)) {
return false;
}
// There are loader events that signal if cached data was missing, rejected,
......
......@@ -40,7 +40,7 @@ import { TestContextService } from 'vs/workbench/test/common/workbenchTestServic
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { MouseInputEvent } from 'vs/base/parts/sandbox/common/electronTypes';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IOSProperties } from 'vs/platform/electron/common/electron';
import { IOSProperties, IOSStatistics } from 'vs/platform/electron/common/electron';
import { ColorScheme } from 'vs/platform/theme/common/theme';
export const TestWorkbenchConfiguration: INativeWorkbenchConfiguration = {
......@@ -198,8 +198,9 @@ export class TestElectronService implements IElectronService {
async showItemInFolder(path: string): Promise<void> { }
async setRepresentedFilename(path: string): Promise<void> { }
async isAdmin(): Promise<boolean> { return false; }
async getTotalMem(): Promise<number> { return 0; }
async getOS(): Promise<IOSProperties> { return Object.create(null); }
async getOSProperties(): Promise<IOSProperties> { return Object.create(null); }
async getOSStatistics(): Promise<IOSStatistics> { return Object.create(null); }
async getOSVirtualMachineHint(): Promise<number> { return 0; }
async killProcess(): Promise<void> { }
async setDocumentEdited(edited: boolean): Promise<void> { }
async openExternal(url: string): Promise<boolean> { return false; }
......
......@@ -60,13 +60,10 @@ import { ICredentialsService } from 'vs/platform/credentials/common/credentials'
import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService';
import { ITunnelService } from 'vs/platform/remote/common/tunnel';
import { TunnelService } from 'vs/platform/remote/node/tunnelService';
import { ITimerService } from 'vs/workbench/services/timer/browser/timerService';
import { TimerService } from 'vs/workbench/services/timer/electron-browser/timerService';
import { IUserDataInitializationService, UserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit';
registerSingleton(ICredentialsService, KeytarCredentialsService, true);
registerSingleton(ITunnelService, TunnelService);
registerSingleton(ITimerService, TimerService);
registerSingleton(IUserDataInitializationService, UserDataInitializationService);
//#endregion
......
......@@ -41,6 +41,12 @@ import 'vs/workbench/services/path/electron-sandbox/pathService';
import 'vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService';
import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ITimerService } from 'vs/workbench/services/timer/browser/timerService';
import { TimerService } from 'vs/workbench/services/timer/electron-sandbox/timerService';
registerSingleton(ITimerService, TimerService);
//#endregion
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册