diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..d5314d13e --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +ui/* diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 26602518b..cc1f66b0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,53 +6,52 @@ on: - v* jobs: - release: - runs-on: ${{ matrix.os }} + release: + runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-latest, ubuntu-latest, windows-latest] + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] - steps: - - name: Check out Git repository - uses: actions/checkout@v2 - with: - submodules: recursive + steps: + - name: Check out Git repository + uses: actions/checkout@v3 + with: + submodules: recursive - - name: Install Node.js, NPM and Yarn - uses: actions/setup-node@v2.1.5 - with: - node-version: 14 + - name: Install Node.js, NPM and Yarn + uses: actions/setup-node@v3 + with: + node-version: 16 - - name: Prepare for app notarization - if: startsWith(matrix.os, 'macos') - # Import Apple API key for app notarization on macOS - run: | - mkdir -p ~/private_keys/ - echo '${{ secrets.api_key }}' > ~/private_keys/AuthKey_${{ secrets.api_key_id }}.p8 + - name: Prepare for app notarization + if: startsWith(matrix.os, 'macos') + # Import Apple API key for app notarization on macOS + run: | + mkdir -p ~/private_keys/ + echo '${{ secrets.api_key }}' > ~/private_keys/AuthKey_${{ secrets.api_key_id }}.p8 - - name: Install libarchive-tools for pacman build # Related https://github.com/electron-userland/electron-builder/issues/4181 - if: startsWith(matrix.os, 'ubuntu') - run: sudo apt-get install libarchive-tools + - name: Install libarchive-tools for pacman build # Related https://github.com/electron-userland/electron-builder/issues/4181 + if: startsWith(matrix.os, 'ubuntu') + run: sudo apt-get install libarchive-tools - - name: Electron Builder Action - uses: samuelmeuli/action-electron-builder@v1.6.0 - with: - # GitHub token, automatically provided to the action - # (No need to define this secret in the repo settings) - github_token: ${{ secrets.github_token }} + - name: Ente Electron Builder Action + uses: ente-io/action-electron-builder@v1.0.0 + with: + # GitHub token, automatically provided to the action + # (No need to define this secret in the repo settings) + github_token: ${{ secrets.github_token }} - # If the commit is tagged with a version (e.g. "v1.0.0"), - # release the app after building - release: ${{ startsWith(github.ref, 'refs/tags/v') }} - - mac_certs: ${{ secrets.mac_certs }} - mac_certs_password: ${{ secrets.mac_certs_password }} - env: - # macOS notarization API key - API_KEY_ID: ${{ secrets.api_key_id }} - API_KEY_ISSUER_ID: ${{ secrets.api_key_issuer_id }} - # setry crash reporting token - SENTRY_AUTH_TOKEN: ${{secrets.sentry_auth_token}} - USE_HARD_LINKS: false + # If the commit is tagged with a version (e.g. "v1.0.0"), + # release the app after building + release: ${{ startsWith(github.ref, 'refs/tags/v') }} + mac_certs: ${{ secrets.mac_certs }} + mac_certs_password: ${{ secrets.mac_certs_password }} + env: + # macOS notarization API key + API_KEY_ID: ${{ secrets.api_key_id }} + API_KEY_ISSUER_ID: ${{ secrets.api_key_issuer_id}} + # setry crash reporting token + SENTRY_AUTH_TOKEN: ${{secrets.sentry_auth_token}} + USE_HARD_LINKS: false diff --git a/.github/workflows/cla.yaml b/.github/workflows/cla.yaml new file mode 100644 index 000000000..25340ec9f --- /dev/null +++ b/.github/workflows/cla.yaml @@ -0,0 +1,38 @@ +name: "CLA Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] + +jobs: + CLAAssistant: + # This job only runs for pull request comments + if: ${{ github.event.issue.pull_request }} + runs-on: ubuntu-latest + steps: + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + # Beta Release + uses: contributor-assistant/github-action@v2.2.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # the below token should have repo scope and must be manually added by you in the repository's secret + PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + with: + path-to-signatures: "signatures/version1/cla.json" + path-to-document: "https://github.com/ente-io/cla/blob/main/CLA.md" # e.g. a CLA or a DCO document + # branch should not be protected + branch: "main" + allowlist: enteio + + # the followings are the optional inputs - If the optional inputs are not given, then default values will be taken + #remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository) + remote-repository-name: cla + #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' + #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' + #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' + #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' + #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' + #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) + #use-dco-flag: true - If you are using DCO instead of CLA diff --git a/CLA.md b/CLA.md new file mode 100644 index 000000000..71c216537 --- /dev/null +++ b/CLA.md @@ -0,0 +1,98 @@ +## Contributor License Agreement + +Thank you for your contribution to ente projects. + +This contributor license agreement documents the rights granted by contributors +to Ente Technologies, Inc ("ente"). This license is for your protection as a +Contributor as well as the protection of ente, its users, and its licensees; you +may still license your own Contributions under other terms. + +In exchange for the ability to participate in the ente community and for other +good consideration, the receipt of which is hereby acknowledged, you accept and +agree to the following terms and conditions for Your present and future +Contributions submitted to ente. Except for the license granted herein to ente +and recipients of software distributed by ente, You reserve all right, title, +and interest in and to Your Contributions. + +1. Definitions. + + "You" (or "Your") shall mean the copyright owner or legal entity authorized + by the copyright owner that is making this Agreement with ente. For legal + entities, the entity making a Contribution and all other entities that + control, are controlled by, or are under common control with that entity are + considered to be a single Contributor. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the direction or + management of such entity, whether by contract or otherwise, or (ii) + ownership of fifty percent (50%) or more of the outstanding shares, or (iii) + beneficial ownership of such entity. + + "Contribution" shall mean any original work of authorship or invention, + including any modifications or additions to an existing work, that is + intentionally submitted by You to ente for inclusion in, or documentation of, + any of the products owned or managed by ente (the "Work"). For the purposes + of this definition, "submitted" means any form of electronic, verbal, or + written communication sent to ente or its representatives, including but not + limited to communication on electronic mailing lists, source code control + systems, and issue tracking systems that are managed by, or on behalf of, + ente for the purpose of discussing and improving the Work, but excluding + communication that is conspicuously marked or otherwise designated in writing + by You as "Not a Contribution." + +2. Grant of Copyright License. Subject to the terms and conditions of this + Agreement, You hereby grant to ente and to recipients of software distributed + by ente a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare derivative works of, + publicly display, publicly perform, and distribute Your Contributions and + such derivative works. + +3. Grant of Patent License. Subject to the terms and conditions of this + Agreement, You hereby grant to ente and to recipients of software distributed + by ente a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable (except as stated in this section) patent license to make, have + made, use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable by You that + are necessarily infringed by Your Contribution(s) alone or by combination of + Your Contribution(s) with the Work to which such Contribution(s) was + submitted. If any entity institutes patent litigation against You or any + other entity (including a cross-claim or counterclaim in a lawsuit) alleging + that your Contribution, or the Work to which you have contributed, + constitutes direct or contributory patent infringement, then any patent + licenses granted to that entity under this Agreement for that Contribution or + Work shall terminate as of the date such litigation is filed. + +4. You represent that you are legally entitled to grant the above license. If + your employer(s) has rights to intellectual property that you create that + includes your Contributions, you represent that you have received permission + to make Contributions on behalf of that employer, that your employer has + waived such rights for your contributions to ente, or that your employer has + executed with ente a separate contributor license agreement substantially + similar to this Agreement. If You are a current employee or contractor of + ente, then the terms of your existing Employment Agreement or Consulting + Services Agreement shall supersede this CLA, and remain in full effect. + +5. You represent that each of Your Contributions is Your original creation (see + section 7 for submissions on behalf of others). You represent that Your + Contribution submissions include complete details of any third-party license + or other restriction (including, but not limited to, related patents and + trademarks) of which you are personally aware and which are associated with + any part of Your Contributions. + +6. You are not expected to provide support for Your Contributions, except to the + extent You desire to provide support. You may provide support for free, for + a fee, or not at all. Unless required by applicable law or agreed to in + writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, + without limitation, any warranties or conditions of title, non-infringement, + merchantability, or fitness for a particular purpose. + +7. Should You wish to submit work that is not Your original creation, You may + submit it to ente separately from any Contribution, identifying the complete + details of its source and of any license or other restriction (including, but + not limited to, related patents, trademarks, and license agreements) of which + you are personally aware, and conspicuously marking the work as "Not a + Contribution". Third-party materials licensed pursuant to: [license name(s) + here]" (substituting the bracketed text with the appropriate license + name(s)). + +8. You agree to notify ente of any facts or circumstances of which you become + aware that would make these representations inaccurate in any respect. diff --git a/build/error.html b/build/error.html index a0199f702..54b787357 100644 --- a/build/error.html +++ b/build/error.html @@ -5,7 +5,7 @@ -
",
"devDependencies": {
@@ -83,6 +83,7 @@
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"concurrently": "^7.0.0",
+ "cross-env": "^7.0.3",
"electron": "^21.2.2",
"electron-builder": "^23.0.3",
"electron-builder-notarize": "^1.2.0",
diff --git a/src/api/imageProcessor.ts b/src/api/imageProcessor.ts
index 61b0ae529..b4464233f 100644
--- a/src/api/imageProcessor.ts
+++ b/src/api/imageProcessor.ts
@@ -1,10 +1,15 @@
+import { CustomErrors } from '../constants/errors';
import { ipcRenderer } from 'electron/renderer';
import { existsSync } from 'fs';
import { writeStream } from '../services/fs';
import { logError } from '../services/logging';
import { ElectronFile } from '../types';
+import { isPlatform } from '../utils/common/platform';
export async function convertHEIC(fileData: Uint8Array): Promise {
+ if (isPlatform('windows')) {
+ throw Error(CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED);
+ }
const convertedFileData = await ipcRenderer.invoke(
'convert-heic',
fileData
@@ -20,6 +25,11 @@ export async function generateImageThumbnail(
let inputFilePath = null;
let createdTempInputFile = null;
try {
+ if (isPlatform('windows')) {
+ throw Error(
+ CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED
+ );
+ }
if (!existsSync(inputFile.path)) {
const tempFilePath = await ipcRenderer.invoke(
'get-temp-file-path',
diff --git a/src/api/watch.ts b/src/api/watch.ts
index d8ff2d1d3..20008375e 100644
--- a/src/api/watch.ts
+++ b/src/api/watch.ts
@@ -4,13 +4,14 @@ import { ipcRenderer } from 'electron';
import { ElectronFile, WatchMapping } from '../types';
import { getElectronFile } from '../services/fs';
import { getWatchMappings, setWatchMappings } from '../services/watch';
+import ElectronLog from 'electron-log';
export async function addWatchMapping(
rootFolderName: string,
folderPath: string,
uploadStrategy: number
) {
- folderPath = path.normalize(folderPath);
+ ElectronLog.log(`Adding watch mapping: ${folderPath}`);
const watchMappings = getWatchMappings();
if (isMappingPresent(watchMappings, folderPath)) {
throw new Error(`Watch mapping already exists`);
@@ -93,23 +94,19 @@ export function registerWatcherFunctions(
) {
ipcRenderer.removeAllListeners('watch-add');
ipcRenderer.removeAllListeners('watch-change');
- ipcRenderer.removeAllListeners('watch-unlink');
+ ipcRenderer.removeAllListeners('watch-unlink-dir');
ipcRenderer.on('watch-add', async (_, filePath: string) => {
- filePath = path.normalize(
- filePath.split(path.sep).join(path.posix.sep)
- );
+ filePath = filePath.split(path.sep).join(path.posix.sep);
+
await addFile(await getElectronFile(filePath));
});
ipcRenderer.on('watch-unlink', async (_, filePath: string) => {
- filePath = path.normalize(
- filePath.split(path.sep).join(path.posix.sep)
- );
+ filePath = filePath.split(path.sep).join(path.posix.sep);
+
await removeFile(filePath);
});
ipcRenderer.on('watch-unlink-dir', async (_, folderPath: string) => {
- folderPath = path.normalize(
- folderPath.split(path.sep).join(path.posix.sep)
- );
+ folderPath = folderPath.split(path.sep).join(path.posix.sep);
await removeFolder(folderPath);
});
}
diff --git a/src/constants/errors.ts b/src/constants/errors.ts
new file mode 100644
index 000000000..43e4773d8
--- /dev/null
+++ b/src/constants/errors.ts
@@ -0,0 +1,5 @@
+export const CustomErrors = {
+ WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED:
+ 'Windows native image processing is not supported',
+ INVALID_OS: (os: string) => `Invalid OS - ${os}`,
+};
diff --git a/src/preload.ts b/src/preload.ts
index 8d2157999..32204839f 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -51,7 +51,10 @@ import { fixHotReloadNext12 } from './utils/preload';
import { isFolder, getDirFiles } from './api/fs';
import { convertHEIC, generateImageThumbnail } from './api/imageProcessor';
import { setupLogging } from './utils/logging';
-import { setupRendererProcessStatsLogger } from './utils/processStats';
+import {
+ setupRendererProcessStatsLogger,
+ logRendererProcessMemoryUsage,
+} from './utils/processStats';
import { runFFmpegCmd } from './api/ffmpeg';
fixHotReloadNext12();
@@ -107,4 +110,5 @@ windowObject['ElectronAPIs'] = {
runFFmpegCmd,
muteUpdateNotification,
generateImageThumbnail,
+ logRendererProcessMemoryUsage,
};
diff --git a/src/services/appUpdater.ts b/src/services/appUpdater.ts
index 84a2bfeba..99ecef8b9 100644
--- a/src/services/appUpdater.ts
+++ b/src/services/appUpdater.ts
@@ -12,7 +12,7 @@ import {
import fetch from 'node-fetch';
import { logErrorSentry } from './sentry';
import ElectronLog from 'electron-log';
-import { isPlatform } from '../utils/main';
+import { isPlatform } from '../utils/common/platform';
const FIVE_MIN_IN_MICROSECOND = 5 * 60 * 1000;
const ONE_DAY_IN_MICROSECOND = 1 * 24 * 60 * 60 * 1000;
diff --git a/src/services/autoLauncher.ts b/src/services/autoLauncher.ts
index c28eb177c..139d5166c 100644
--- a/src/services/autoLauncher.ts
+++ b/src/services/autoLauncher.ts
@@ -1,4 +1,4 @@
-import { isPlatform } from '../utils/main';
+import { isPlatform } from '../utils/common/platform';
import { AutoLauncherClient } from '../types/autoLauncher';
import linuxAutoLauncher from './autoLauncherClients/linuxAutoLauncher';
import macAndWindowsAutoLauncher from './autoLauncherClients/macAndWindowsAutoLauncher';
diff --git a/src/services/fs.ts b/src/services/fs.ts
index 9565cb086..b5ef8eb11 100644
--- a/src/services/fs.ts
+++ b/src/services/fs.ts
@@ -184,12 +184,22 @@ export const getZipFileStream = async (
};
export async function isFolder(dirPath: string) {
- return await fs
- .stat(dirPath)
- .then((stats) => {
- return stats.isDirectory();
- })
- .catch(() => false);
+ try {
+ const stats = await fs.stat(dirPath);
+ return stats.isDirectory();
+ } catch (e) {
+ let err = e;
+ // if code is defined, it's an error from fs.stat
+ if (typeof e.code !== 'undefined') {
+ // ENOENT means the file does not exist
+ if (e.code === 'ENOENT') {
+ return false;
+ }
+ err = Error(`fs error code: ${e.code}`);
+ }
+ logError(err, 'isFolder failed');
+ return false;
+ }
}
export const convertBrowserStreamToNode = (
diff --git a/src/services/imageProcessor.ts b/src/services/imageProcessor.ts
index e211e2b64..05b252ba7 100644
--- a/src/services/imageProcessor.ts
+++ b/src/services/imageProcessor.ts
@@ -5,10 +5,11 @@ import { existsSync, rmSync } from 'fs';
import { readFile, writeFile } from 'promise-fs';
import { generateTempFilePath } from '../utils/temp';
import { logErrorSentry } from './sentry';
-import { isPlatform } from '../utils/main';
+import { isPlatform } from '../utils/common/platform';
import { isDev } from '../utils/common';
import path from 'path';
import log from 'electron-log';
+import { CustomErrors } from '../constants/errors';
const shellescape = require('any-shell-escape');
const asyncExec = util.promisify(exec);
@@ -157,7 +158,7 @@ function constructConvertCommand(
}
);
} else {
- Error(`${process.platform} native heic convert not supported yet`);
+ throw Error(CustomErrors.INVALID_OS(process.platform));
}
return convertCmd;
}
@@ -271,9 +272,7 @@ function constructThumbnailGenerationCommand(
return cmdPart;
});
} else {
- Error(
- `${process.platform} native thumbnail generation not supported yet`
- );
+ throw Error(CustomErrors.INVALID_OS(process.platform));
}
return thumbnailGenerationCmd;
}
diff --git a/src/utils/common.ts b/src/utils/common/index.ts
similarity index 100%
rename from src/utils/common.ts
rename to src/utils/common/index.ts
diff --git a/src/utils/common/platform.ts b/src/utils/common/platform.ts
new file mode 100644
index 000000000..2ee705d5f
--- /dev/null
+++ b/src/utils/common/platform.ts
@@ -0,0 +1,11 @@
+export function isPlatform(platform: 'mac' | 'windows' | 'linux') {
+ if (process.platform === 'darwin') {
+ return platform === 'mac';
+ } else if (process.platform === 'win32') {
+ return platform === 'windows';
+ } else if (process.platform === 'linux') {
+ return platform === 'linux';
+ } else {
+ return false;
+ }
+}
diff --git a/src/utils/createWindow.ts b/src/utils/createWindow.ts
index db356d467..391a8e285 100644
--- a/src/utils/createWindow.ts
+++ b/src/utils/createWindow.ts
@@ -3,9 +3,11 @@ import * as path from 'path';
import { isDev } from './common';
import { isAppQuitting } from '../main';
import { PROD_HOST_URL } from '../config';
-import { isPlatform } from './main';
+import { isPlatform } from './common/platform';
import { getHideDockIconPreference } from '../services/userPreference';
import autoLauncher from '../services/autoLauncher';
+import ElectronLog from 'electron-log';
+import { logErrorSentry } from '../services/sentry';
export async function createWindow(): Promise {
const appImgPath = isDev
@@ -64,6 +66,20 @@ export async function createWindow(): Promise {
// ignore
}
});
+ mainWindow.webContents.on('render-process-gone', (event, details) => {
+ mainWindow.webContents.reload();
+ logErrorSentry(
+ Error('render-process-gone'),
+ 'webContents event render-process-gone',
+ { details }
+ );
+ ElectronLog.log('webContents event render-process-gone', details);
+ });
+ mainWindow.webContents.on('unresponsive', () => {
+ mainWindow.webContents.forcefullyCrashRenderer();
+ ElectronLog.log('webContents event unresponsive');
+ });
+
setTimeout(() => {
try {
splash.destroy();
diff --git a/src/utils/main.ts b/src/utils/main.ts
index 81fedbf7a..729bc3d3b 100644
--- a/src/utils/main.ts
+++ b/src/utils/main.ts
@@ -11,6 +11,7 @@ import { getHideDockIconPreference } from '../services/userPreference';
import { setupAutoUpdater } from '../services/appUpdater';
import ElectronLog from 'electron-log';
import os from 'os';
+import { isPlatform } from './common/platform';
export function handleUpdates(mainWindow: BrowserWindow) {
if (!isDev) {
@@ -84,18 +85,6 @@ export function setupNextElectronServe() {
});
}
-export function isPlatform(platform: 'mac' | 'windows' | 'linux') {
- if (process.platform === 'darwin') {
- return platform === 'mac';
- } else if (process.platform === 'win32') {
- return platform === 'windows';
- } else if (process.platform === 'linux') {
- return platform === 'linux';
- } else {
- return false;
- }
-}
-
export async function handleDockIconHideOnAutoLaunch() {
const shouldHideDockIcon = getHideDockIconPreference();
const wasAutoLaunched = await autoLauncher.wasAutoLaunched();
diff --git a/src/utils/menu.ts b/src/utils/menu.ts
index 5002a1205..6ecb8459b 100644
--- a/src/utils/menu.ts
+++ b/src/utils/menu.ts
@@ -11,7 +11,7 @@ import {
} from '../services/userPreference';
import { setIsAppQuitting } from '../main';
import autoLauncher from '../services/autoLauncher';
-import { isPlatform } from './main';
+import { isPlatform } from './common/platform';
import ElectronLog from 'electron-log';
export function buildContextMenu(
diff --git a/src/utils/processStats.ts b/src/utils/processStats.ts
index 64f900d58..00b3a71d1 100644
--- a/src/utils/processStats.ts
+++ b/src/utils/processStats.ts
@@ -5,9 +5,9 @@ const LOGGING_INTERVAL_IN_MICROSECONDS = 30 * 1000; // 30 seconds
const SPIKE_DETECTION_INTERVAL_IN_MICROSECONDS = 1 * 1000; // 1 seconds
-const MAIN_MEMORY_USAGE_DIFF_IN_KILOBYTES_CONSIDERED_AS_SPIKE = 10 * 1024; // 10 MB
+const MAIN_MEMORY_USAGE_DIFF_IN_KILOBYTES_CONSIDERED_AS_SPIKE = 50 * 1024; // 50 MB
-const HIGH_MAIN_MEMORY_USAGE_THRESHOLD_IN_KILOBYTES = 100 * 1024; // 100 MB
+const HIGH_MAIN_MEMORY_USAGE_THRESHOLD_IN_KILOBYTES = 200 * 1024; // 200 MB
const RENDERER_MEMORY_USAGE_DIFF_IN_KILOBYTES_CONSIDERED_AS_SPIKE = 200 * 1024; // 200 MB
@@ -40,15 +40,15 @@ let mainProcessUsingHighMemory = false;
async function logSpikeMainMemoryUsage() {
const processMemoryInfo = await process.getProcessMemoryInfo();
const currentMemoryUsage = Math.max(
- processMemoryInfo.residentSet,
+ processMemoryInfo.residentSet ?? 0,
processMemoryInfo.private
);
- const previewMemoryUsage = Math.max(
- previousMainProcessMemoryInfo.private,
- previousMainProcessMemoryInfo.residentSet
+ const previousMemoryUsage = Math.max(
+ previousMainProcessMemoryInfo.residentSet ?? 0,
+ previousMainProcessMemoryInfo.private
);
const isSpiking =
- currentMemoryUsage - previewMemoryUsage >=
+ currentMemoryUsage - previousMemoryUsage >=
MAIN_MEMORY_USAGE_DIFF_IN_KILOBYTES_CONSIDERED_AS_SPIKE;
const isHighMemoryUsage =
@@ -92,15 +92,16 @@ let rendererUsingHighMemory = false;
async function logSpikeRendererMemoryUsage() {
const processMemoryInfo = await process.getProcessMemoryInfo();
const currentMemoryUsage = Math.max(
- processMemoryInfo.residentSet,
+ processMemoryInfo.residentSet ?? 0,
processMemoryInfo.private
);
- const previewMemoryUsage = Math.max(
+
+ const previousMemoryUsage = Math.max(
previousRendererProcessMemoryInfo.private,
- previousRendererProcessMemoryInfo.residentSet
+ previousRendererProcessMemoryInfo.residentSet ?? 0
);
const isSpiking =
- currentMemoryUsage - previewMemoryUsage >=
+ currentMemoryUsage - previousMemoryUsage >=
RENDERER_MEMORY_USAGE_DIFF_IN_KILOBYTES_CONSIDERED_AS_SPIKE;
const isHighMemoryUsage =
@@ -168,6 +169,19 @@ export function setupRendererProcessStatsLogger() {
setInterval(logRendererProcessStats, LOGGING_INTERVAL_IN_MICROSECONDS);
}
+export async function logRendererProcessMemoryUsage(message: string) {
+ const processMemoryInfo = await process.getProcessMemoryInfo();
+ const processMemory = Math.max(
+ processMemoryInfo.private,
+ processMemoryInfo.residentSet ?? 0
+ );
+ ElectronLog.log(
+ 'renderer ProcessMemory',
+ message,
+ convertBytesToHumanReadable(processMemory * 1024)
+ );
+}
+
const getNormalizedProcessMemoryInfo = async (
processMemoryInfo: Electron.ProcessMemoryInfo
) => {
diff --git a/ui b/ui
index 0d34202c4..c56da8716 160000
--- a/ui
+++ b/ui
@@ -1 +1 @@
-Subproject commit 0d34202c4121003defea9839355f5c03d238d2c9
+Subproject commit c56da87161ba582ae21407b2d3a19508b50c8b9b
diff --git a/yarn.lock b/yarn.lock
index 8dd73a05c..a406a638e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1199,6 +1199,13 @@ crc@^3.8.0:
dependencies:
buffer "^5.1.0"
+cross-env@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
+ integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
+ dependencies:
+ cross-spawn "^7.0.1"
+
cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"