mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-27 19:07:15 +08:00
[local-sync] Throttle message processing when on battery
Summary: We don't want to run message processing full tilt when a user isn't plugged in. This diff adds some detection logic that causes message processing to be throttled/unthrottled when a user unplugs/plugs in their computer. Test Plan: Run locally unplugged and plugged in, verify that CPU use goes up/down Reviewers: evan, juan Reviewed By: juan Differential Revision: https://phab.nylas.com/D3759
This commit is contained in:
parent
9f5631b1fe
commit
ac6ad38296
1 changed files with 37 additions and 3 deletions
|
@ -12,6 +12,9 @@ const LocalDatabaseConnector = require('../shared/local-database-connector');
|
|||
|
||||
const MAX_QUEUE_LENGTH = 500
|
||||
const PROCESSING_DELAY = 0
|
||||
const MAX_CPU_USE_ON_AC = 1.0;
|
||||
const MAX_CPU_USE_ON_BATTERY = 0.10;
|
||||
const MAX_CHUNK_SIZE = 1;
|
||||
|
||||
class MessageProcessor {
|
||||
|
||||
|
@ -19,6 +22,15 @@ class MessageProcessor {
|
|||
// The queue is a chain of Promises
|
||||
this._queue = Promise.resolve()
|
||||
this._queueLength = 0
|
||||
this._currentChunkSize = 0
|
||||
this._currentChunkStart = Date.now();
|
||||
this._isBatteryCharging = true;
|
||||
navigator.getBattery().then((battery) => {
|
||||
battery.addEventListener('chargingchange', () => {
|
||||
console.info('charge change', battery.charging);
|
||||
this._isBatteryCharging = battery.charging
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
queueLength() {
|
||||
|
@ -29,6 +41,19 @@ class MessageProcessor {
|
|||
return this._queueLength >= MAX_QUEUE_LENGTH
|
||||
}
|
||||
|
||||
_maxCPUForProcessing() {
|
||||
if (this._isBatteryCharging) {
|
||||
return MAX_CPU_USE_ON_AC;
|
||||
}
|
||||
return MAX_CPU_USE_ON_BATTERY;
|
||||
}
|
||||
|
||||
_computeThrottlingTimeout() {
|
||||
const timeSliceMs = Date.now() - this._currentChunkStart;
|
||||
const maxCPU = this._maxCPUForProcessing();
|
||||
return (timeSliceMs * (1.0 / maxCPU)) - timeSliceMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns Promise that resolves when message has been processed
|
||||
* This promise will never reject, given that this function is meant to be
|
||||
|
@ -40,9 +65,21 @@ class MessageProcessor {
|
|||
return new Promise((resolve) => {
|
||||
this._queueLength++
|
||||
this._queue = this._queue.then(async () => {
|
||||
if (this._currentChunkSize === 0) {
|
||||
this._currentChunkStart = Date.now();
|
||||
}
|
||||
this._currentChunkSize++;
|
||||
|
||||
await this._processMessage({accountId, folderId, imapMessage, struct, desiredParts})
|
||||
this._queueLength--
|
||||
|
||||
// Throttle message processing to meter cpu usage
|
||||
if (this._currentChunkSize === MAX_CHUNK_SIZE) {
|
||||
const timeout = this._computeThrottlingTimeout();
|
||||
await new Promise(r => setTimeout(r, timeout))
|
||||
this._currentChunkSize = 0;
|
||||
}
|
||||
|
||||
// To save memory, we reset the Promise chain if the queue reaches a
|
||||
// length of 0, otherwise we will continue referencing the entire chain
|
||||
// of promises that came before
|
||||
|
@ -50,9 +87,6 @@ class MessageProcessor {
|
|||
this._queue = Promise.resolve()
|
||||
}
|
||||
resolve()
|
||||
|
||||
// Throttle message processing to meter cpu usage
|
||||
await new Promise(r => setTimeout(r, PROCESSING_DELAY))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue