From ca2afdc2026c624ce9a22ca178de272cc9cddba0 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 15:17:14 -0400 Subject: [PATCH 01/14] Add `desktop-idle` dependency --- package.json | 1 + yarn.lock | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/package.json b/package.json index 88b0bf7d5..6a3e6dab1 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "bunyan": "^1.8.12", "config": "^1.28.1", "decompress": "^4.2.0", + "desktop-idle": "^1.1.1", "electron-config": "^1.0.0", "electron-editor-context-menu": "^1.1.1", "electron-is-dev": "^0.3.0", diff --git a/yarn.lock b/yarn.lock index 1c798e11c..60faa966b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,6 +1350,10 @@ depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" +desktop-idle@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/desktop-idle/-/desktop-idle-1.1.1.tgz#bbbd17d3ad8aa67ef069b0bbe8e39c88612b9d36" + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" From 3140e4d66d5afde2eceaf1cdb93fb99903e11df3 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 15:17:32 -0400 Subject: [PATCH 02/14] Implement basic `IdleListener` --- js/modules/idle_listener.js | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 js/modules/idle_listener.js diff --git a/js/modules/idle_listener.js b/js/modules/idle_listener.js new file mode 100644 index 000000000..d7ce3ba37 --- /dev/null +++ b/js/modules/idle_listener.js @@ -0,0 +1,39 @@ +const desktopIdle = require('desktop-idle'); +const EventEmitter = require('events'); + + +const POLL_INTERVAL_MS = 10 * 1000; +const IDLE_THRESHOLD_MS = POLL_INTERVAL_MS; + +class IdleListener extends EventEmitter { + constructor() { + super(); + this.intervalId = null; + } + + start() { + this.stop(); + this.intervalId = setInterval(() => { + const idleDuration = desktopIdle.getIdleTime(); + const isIdle = idleDuration >= (IDLE_THRESHOLD_MS / 1000); + if (!isIdle) { + return; + } + + this.emit('idle', { idleDuration }); + + }, POLL_INTERVAL_MS); + } + + stop() { + if (!this.intervalId) { + return; + } + + clearInterval(this.intervalId); + } +} + +module.exports = { + IdleListener, +}; From 92ace6784629f3f508ed466884e511867e59acfc Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 15:17:53 -0400 Subject: [PATCH 03/14] Start idle listener on startup --- js/background.js | 9 +++++++++ preload.js | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/js/background.js b/js/background.js index ca2a59ffa..a39bc59f2 100644 --- a/js/background.js +++ b/js/background.js @@ -14,6 +14,7 @@ ;(function() { 'use strict'; + const { IdleListener } = Signal; const { Errors, Message } = window.Signal.Types; const { upgradeMessageSchema } = window.Signal.Migrations; @@ -75,6 +76,11 @@ storage.fetch(); + const idleListener = new IdleListener(); + idleListener.on('idle', (event) => { + console.log('Detected user idle:', event); + }); + // We need this 'first' check because we don't want to start the app up any other time // than the first time. And storage.fetch() will cause onready() to fire. var first = true; @@ -85,9 +91,12 @@ first = false; ConversationController.load().then(start, start); + idleListener.start(); }); Whisper.events.on('shutdown', function() { + idleListener.stop(); + if (messageReceiver) { messageReceiver.close().then(function() { Whisper.events.trigger('shutdown-complete'); diff --git a/preload.js b/preload.js index 151856242..cae0288e8 100644 --- a/preload.js +++ b/preload.js @@ -123,6 +123,10 @@ Message.upgradeSchema(message, upgradeSchemaContext); window.Signal = window.Signal || {}; + + const { IdleListener} = require('./js/modules/idle_listener'); + window.Signal.IdleListener = IdleListener; + window.Signal.Logs = require('./js/modules/logs'); window.Signal.OS = require('./js/modules/os'); window.Signal.Backup = require('./js/modules/backup'); From d13668544d5625c0aec83567960887029e1e333b Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 15:21:38 -0400 Subject: [PATCH 04/14] Rename `IdleListener` to `IdleDetector` --- js/background.js | 4 ++-- .../{idle_listener.js => idle_detector.js} | 16 ++++++++-------- preload.js | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) rename js/modules/{idle_listener.js => idle_detector.js} (54%) diff --git a/js/background.js b/js/background.js index a39bc59f2..c48c3bcc3 100644 --- a/js/background.js +++ b/js/background.js @@ -14,7 +14,7 @@ ;(function() { 'use strict'; - const { IdleListener } = Signal; + const { IdleDetector } = Signal; const { Errors, Message } = window.Signal.Types; const { upgradeMessageSchema } = window.Signal.Migrations; @@ -76,7 +76,7 @@ storage.fetch(); - const idleListener = new IdleListener(); + const idleListener = new IdleDetector(); idleListener.on('idle', (event) => { console.log('Detected user idle:', event); }); diff --git a/js/modules/idle_listener.js b/js/modules/idle_detector.js similarity index 54% rename from js/modules/idle_listener.js rename to js/modules/idle_detector.js index d7ce3ba37..0ac975b64 100644 --- a/js/modules/idle_listener.js +++ b/js/modules/idle_detector.js @@ -2,10 +2,10 @@ const desktopIdle = require('desktop-idle'); const EventEmitter = require('events'); -const POLL_INTERVAL_MS = 10 * 1000; -const IDLE_THRESHOLD_MS = POLL_INTERVAL_MS; +const POLL_INTERVAL = 10; // seconds +const IDLE_THRESHOLD = POLL_INTERVAL; -class IdleListener extends EventEmitter { +class IdleDetector extends EventEmitter { constructor() { super(); this.intervalId = null; @@ -14,15 +14,15 @@ class IdleListener extends EventEmitter { start() { this.stop(); this.intervalId = setInterval(() => { - const idleDuration = desktopIdle.getIdleTime(); - const isIdle = idleDuration >= (IDLE_THRESHOLD_MS / 1000); + const idleDurationInSeconds = desktopIdle.getIdleTime(); + const isIdle = idleDurationInSeconds >= IDLE_THRESHOLD; if (!isIdle) { return; } - this.emit('idle', { idleDuration }); + this.emit('idle', { idleDurationInSeconds }); - }, POLL_INTERVAL_MS); + }, POLL_INTERVAL * 1000); } stop() { @@ -35,5 +35,5 @@ class IdleListener extends EventEmitter { } module.exports = { - IdleListener, + IdleDetector, }; diff --git a/preload.js b/preload.js index cae0288e8..029df59a6 100644 --- a/preload.js +++ b/preload.js @@ -124,8 +124,8 @@ window.Signal = window.Signal || {}; - const { IdleListener} = require('./js/modules/idle_listener'); - window.Signal.IdleListener = IdleListener; + const { IdleDetector} = require('./js/modules/idle_detector'); + window.Signal.IdleDetector = IdleDetector; window.Signal.Logs = require('./js/modules/logs'); window.Signal.OS = require('./js/modules/os'); From 09ee2d4ea296ed02d8cb5e4d4172d83ddf98979d Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 15:45:39 -0400 Subject: [PATCH 05/14] Switch to using `requestIdleCallback` Example: https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API#Example --- js/modules/idle_detector.js | 43 +++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/js/modules/idle_detector.js b/js/modules/idle_detector.js index 0ac975b64..2404b304e 100644 --- a/js/modules/idle_detector.js +++ b/js/modules/idle_detector.js @@ -1,36 +1,43 @@ -const desktopIdle = require('desktop-idle'); +/* eslint-env browser */ + const EventEmitter = require('events'); -const POLL_INTERVAL = 10; // seconds -const IDLE_THRESHOLD = POLL_INTERVAL; +const POLL_INTERVAL_MS = 10 * 1000; +const IDLE_THRESHOLD_MS = 25; class IdleDetector extends EventEmitter { constructor() { super(); - this.intervalId = null; + this.handle = null; + this.timeoutId = null; } start() { - this.stop(); - this.intervalId = setInterval(() => { - const idleDurationInSeconds = desktopIdle.getIdleTime(); - const isIdle = idleDurationInSeconds >= IDLE_THRESHOLD; - if (!isIdle) { - return; - } - - this.emit('idle', { idleDurationInSeconds }); - - }, POLL_INTERVAL * 1000); + this._scheduleNextCallback(); } stop() { - if (!this.intervalId) { - return; + if (this.handle) { + cancelIdleCallback(this.handle); } - clearInterval(this.intervalId); + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + } + + _scheduleNextCallback() { + this.stop(); + this.handle = requestIdleCallback((deadline) => { + const { didTimeout } = deadline; + const timeRemaining = deadline.timeRemaining(); + const isIdle = timeRemaining >= IDLE_THRESHOLD_MS; + if (isIdle || didTimeout) { + this.emit('idle', { timestamp: Date.now(), didTimeout, timeRemaining }); + } + this.timeoutId = setTimeout(() => this._scheduleNextCallback(), POLL_INTERVAL_MS); + }); } } From 0b7ce39ff7b7d9133a4c774d00772748eefbe64c Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 20:03:28 -0400 Subject: [PATCH 06/14] Remove `desktop-idle` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’d rather not rely on a native dependency for this functionality. --- package.json | 1 - yarn.lock | 4 ---- 2 files changed, 5 deletions(-) diff --git a/package.json b/package.json index 6a3e6dab1..88b0bf7d5 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "bunyan": "^1.8.12", "config": "^1.28.1", "decompress": "^4.2.0", - "desktop-idle": "^1.1.1", "electron-config": "^1.0.0", "electron-editor-context-menu": "^1.1.1", "electron-is-dev": "^0.3.0", diff --git a/yarn.lock b/yarn.lock index 60faa966b..1c798e11c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,10 +1350,6 @@ depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" -desktop-idle@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/desktop-idle/-/desktop-idle-1.1.1.tgz#bbbd17d3ad8aa67ef069b0bbe8e39c88612b9d36" - detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" From 8e762797c0f14e436499a5ef2d46126544a095c6 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 18:24:38 -0400 Subject: [PATCH 07/14] Remove attachment validation Turns out `fileName` is optional and maybe even `contentType`. We should revisit this at a later point in time. --- js/modules/types/attachment.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/js/modules/types/attachment.js b/js/modules/types/attachment.js index cb257c212..d37a95454 100644 --- a/js/modules/types/attachment.js +++ b/js/modules/types/attachment.js @@ -29,8 +29,9 @@ const { migrateDataToFileSystem } = require('./attachment/migrate_data_to_file_s // schemaVersion: integer // } -// Returns true if `rawAttachment` is a valid attachment based on our (limited) -// criteria. Over time, we can expand this definition to become more narrow: +// Returns true if `rawAttachment` is a valid attachment based on our current schema. +// Over time, we can expand this definition to become more narrow, e.g. require certain +// fields, etc. exports.isValid = (rawAttachment) => { // NOTE: We cannot use `_.isPlainObject` because `rawAttachment` is // deserialized by protobuf: @@ -38,10 +39,7 @@ exports.isValid = (rawAttachment) => { return false; } - const hasValidContentType = isString(rawAttachment.contentType); - const hasValidFileName = - isString(rawAttachment.fileName) || rawAttachment.fileName === null; - return hasValidContentType && hasValidFileName; + return true; }; // Upgrade steps From ca28f3030b75aece34ee2ad74700f860f74ebd95 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 19:37:39 -0400 Subject: [PATCH 08/14] Add `MessageMigration` module --- js/modules/messages_migration.js | 99 ++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 js/modules/messages_migration.js diff --git a/js/modules/messages_migration.js b/js/modules/messages_migration.js new file mode 100644 index 000000000..c1b4f3e0d --- /dev/null +++ b/js/modules/messages_migration.js @@ -0,0 +1,99 @@ +const isNumber = require('lodash/isNumber'); +const isFunction = require('lodash/isFunction'); +const Message = require('./types/message'); + + +const processNext = async ({ + BackboneMessage, + BackboneMessageCollection, + count, + upgradeMessageSchema, + wrapDeferred, +} = {}) => { + if (!isFunction(BackboneMessage)) { + throw new TypeError('`BackboneMessage` (Whisper.Message) constructor is required'); + } + + if (!isFunction(BackboneMessageCollection)) { + throw new TypeError('`BackboneMessageCollection` (Whisper.MessageCollection)' + + ' constructor is required'); + } + + if (!isNumber(count)) { + throw new TypeError('`count` is required'); + } + + if (!isFunction(upgradeMessageSchema)) { + throw new TypeError('`upgradeMessageSchema` is required'); + } + + if (!isFunction(wrapDeferred)) { + throw new TypeError('`wrapDeferred` is required'); + } + + const startTime = Date.now(); + + const startFetchTime = Date.now(); + const messagesRequiringSchemaUpgrade = + await _fetchMessagesRequiringSchemaUpgrade({ BackboneMessageCollection, count }); + const fetchDuration = Date.now() - startFetchTime; + + const startUpgradeTime = Date.now(); + const upgradedMessages = + await Promise.all(messagesRequiringSchemaUpgrade.map(upgradeMessageSchema)); + const upgradeDuration = Date.now() - startUpgradeTime; + + const startSaveTime = Date.now(); + const saveMessage = _saveMessage({ BackboneMessage, wrapDeferred }); + await Promise.all(upgradedMessages.map(saveMessage)); + const saveDuration = Date.now() - startSaveTime; + + const totalDuration = Date.now() - startTime; + const numProcessed = messagesRequiringSchemaUpgrade.length; + const hasMore = numProcessed > 0; + return { + hasMore, + numProcessed, + fetchDuration, + upgradeDuration, + saveDuration, + totalDuration, + }; +}; + +const _saveMessage = ({ BackboneMessage, wrapDeferred } = {}) => (message) => { + const backboneMessage = new BackboneMessage(message); + return wrapDeferred(backboneMessage.save()); +}; + +const _fetchMessagesRequiringSchemaUpgrade = + async ({ BackboneMessageCollection, count } = {}) => { + if (!isFunction(BackboneMessageCollection)) { + throw new TypeError('`BackboneMessageCollection` (Whisper.MessageCollection)' + + ' constructor is required'); + } + + if (!isNumber(count)) { + throw new TypeError('`count` is required'); + } + + const collection = new BackboneMessageCollection(); + return new Promise(resolve => collection.fetch({ + limit: count, + index: { + name: 'schemaVersion', + upper: Message.CURRENT_SCHEMA_VERSION, + excludeUpper: true, + order: 'desc', + }, + }).always(() => { + const models = collection.models || []; + const messages = models.map(model => model.toJSON()); + resolve(messages); + })); + }; + + +module.exports = { + processNext, +}; From 4651cbc2eba2ddbcba5934bc82d493610415907c Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 19:47:38 -0400 Subject: [PATCH 09/14] Improve ``Message.upgradeSchema` preconditions --- js/background.js | 2 +- js/modules/types/message.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/js/background.js b/js/background.js index c48c3bcc3..d4cbb8a2b 100644 --- a/js/background.js +++ b/js/background.js @@ -14,7 +14,7 @@ ;(function() { 'use strict'; - const { IdleDetector } = Signal; + const { IdleDetector, MessageMigration } = Signal; const { Errors, Message } = window.Signal.Types; const { upgradeMessageSchema } = window.Signal.Migrations; diff --git a/js/modules/types/message.js b/js/modules/types/message.js index b4680818f..a43e9c664 100644 --- a/js/modules/types/message.js +++ b/js/modules/types/message.js @@ -166,8 +166,13 @@ const toVersion3 = exports._withSchemaVersion( ); // UpgradeStep -exports.upgradeSchema = async (message, { writeAttachmentData } = {}) => - toVersion3( +exports.upgradeSchema = async (message, { writeAttachmentData } = {}) => { + if (!isFunction(writeAttachmentData)) { + throw new TypeError('`context.writeAttachmentData` is required'); + } + + return toVersion3( await toVersion2(await toVersion1(await toVersion0(message))), { writeAttachmentData } ); +}; From 5c9f18e1ae21f90d749de35de151fc08579e2d64 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 21 Mar 2018 19:48:27 -0400 Subject: [PATCH 10/14] Wire up background message migration --- js/background.js | 26 +++++++++++++++++++++----- preload.js | 6 +++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/js/background.js b/js/background.js index d4cbb8a2b..ed5e0667d 100644 --- a/js/background.js +++ b/js/background.js @@ -76,10 +76,26 @@ storage.fetch(); - const idleListener = new IdleDetector(); - idleListener.on('idle', (event) => { - console.log('Detected user idle:', event); + + /* eslint-enable */ + /* jshint ignore:start */ + const idleDetector = new IdleDetector(); + idleDetector.on('idle', async () => { + const results = await MessageMigration.processNext({ + BackboneMessage: Whisper.Message, + BackboneMessageCollection: Whisper.MessageCollection, + count: 3, + upgradeMessageSchema, + wrapDeferred, }); + console.log('Message schema upgrade:', results); + + if (!results.hasMore) { + idleDetector.stop(); + } + }); + /* jshint ignore:end */ + /* eslint-disable */ // We need this 'first' check because we don't want to start the app up any other time // than the first time. And storage.fetch() will cause onready() to fire. @@ -91,11 +107,11 @@ first = false; ConversationController.load().then(start, start); - idleListener.start(); + idleDetector.start(); }); Whisper.events.on('shutdown', function() { - idleListener.stop(); + idleDetector.stop(); if (messageReceiver) { messageReceiver.close().then(function() { diff --git a/preload.js b/preload.js index 029df59a6..7a8defd34 100644 --- a/preload.js +++ b/preload.js @@ -122,12 +122,12 @@ const upgradeMessageSchema = message => Message.upgradeSchema(message, upgradeSchemaContext); - window.Signal = window.Signal || {}; - const { IdleDetector} = require('./js/modules/idle_detector'); - window.Signal.IdleDetector = IdleDetector; + window.Signal = window.Signal || {}; + window.Signal.IdleDetector = IdleDetector; window.Signal.Logs = require('./js/modules/logs'); + window.Signal.MessageMigration = require('./js/modules/messages_migration'); window.Signal.OS = require('./js/modules/os'); window.Signal.Backup = require('./js/modules/backup'); window.Signal.Crypto = require('./js/modules/crypto'); From 4a7cc22de31f163d907baa330e3f837d1191c5a5 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Fri, 23 Mar 2018 10:11:01 -0400 Subject: [PATCH 11/14] :art: Use `window.requestIdleCallback` --- js/modules/idle_detector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/modules/idle_detector.js b/js/modules/idle_detector.js index 2404b304e..384074ace 100644 --- a/js/modules/idle_detector.js +++ b/js/modules/idle_detector.js @@ -29,7 +29,7 @@ class IdleDetector extends EventEmitter { _scheduleNextCallback() { this.stop(); - this.handle = requestIdleCallback((deadline) => { + this.handle = window.requestIdleCallback((deadline) => { const { didTimeout } = deadline; const timeRemaining = deadline.timeRemaining(); const isIdle = timeRemaining >= IDLE_THRESHOLD_MS; From 7c2fde443354d50784c566cf05fe54f1843b6b6a Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Fri, 23 Mar 2018 10:16:37 -0400 Subject: [PATCH 12/14] Add `Signal.Workflow` namespace --- js/background.js | 6 +++--- ...messages_migration.js => messages_data_migrator.js} | 0 preload.js | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) rename js/modules/{messages_migration.js => messages_data_migrator.js} (100%) diff --git a/js/background.js b/js/background.js index ed5e0667d..f11480993 100644 --- a/js/background.js +++ b/js/background.js @@ -14,7 +14,7 @@ ;(function() { 'use strict'; - const { IdleDetector, MessageMigration } = Signal; + const { IdleDetector, MessageDataMigrator } = Signal.Workflow; const { Errors, Message } = window.Signal.Types; const { upgradeMessageSchema } = window.Signal.Migrations; @@ -77,11 +77,11 @@ storage.fetch(); - /* eslint-enable */ + /* eslint-enable */ /* jshint ignore:start */ const idleDetector = new IdleDetector(); idleDetector.on('idle', async () => { - const results = await MessageMigration.processNext({ + const results = await MessageDataMigrator.processNext({ BackboneMessage: Whisper.Message, BackboneMessageCollection: Whisper.MessageCollection, count: 3, diff --git a/js/modules/messages_migration.js b/js/modules/messages_data_migrator.js similarity index 100% rename from js/modules/messages_migration.js rename to js/modules/messages_data_migrator.js diff --git a/preload.js b/preload.js index 7a8defd34..3528fc75f 100644 --- a/preload.js +++ b/preload.js @@ -125,23 +125,25 @@ const { IdleDetector} = require('./js/modules/idle_detector'); window.Signal = window.Signal || {}; - window.Signal.IdleDetector = IdleDetector; - window.Signal.Logs = require('./js/modules/logs'); - window.Signal.MessageMigration = require('./js/modules/messages_migration'); - window.Signal.OS = require('./js/modules/os'); window.Signal.Backup = require('./js/modules/backup'); window.Signal.Crypto = require('./js/modules/crypto'); + window.Signal.Logs = require('./js/modules/logs'); window.Signal.Migrations = {}; window.Signal.Migrations.loadAttachmentData = Attachment.loadData(readAttachmentData); window.Signal.Migrations.deleteAttachmentData = Attachment.deleteData(deleteAttachmentData); window.Signal.Migrations.upgradeMessageSchema = upgradeMessageSchema; window.Signal.Migrations.V17 = require('./js/modules/migrations/17'); + window.Signal.OS = require('./js/modules/os'); window.Signal.Types = window.Signal.Types || {}; window.Signal.Types.Attachment = Attachment; window.Signal.Types.Errors = require('./js/modules/types/errors'); window.Signal.Types.Message = Message; window.Signal.Types.MIME = require('./js/modules/types/mime'); window.Signal.Types.Settings = require('./js/modules/types/settings'); + window.Signal.Workflow = {}; + window.Signal.Workflow.IdleDetector = IdleDetector; + window.Signal.Workflow.MessageDataMigrator = + require('./js/modules/messages_data_migrator'); // We pull this in last, because the native module involved appears to be sensitive to // /tmp mounted as noexec on Linux. From 9b112489cdcbdb99fe9d1558e309b1907b0c1e2b Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Fri, 23 Mar 2018 10:17:06 -0400 Subject: [PATCH 13/14] Upgrade 2 messages every 30 seconds This results in 4 messages per minute or 240 messages per hour. --- js/background.js | 5 +++-- js/modules/idle_detector.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js/background.js b/js/background.js index f11480993..27018df5c 100644 --- a/js/background.js +++ b/js/background.js @@ -79,16 +79,17 @@ /* eslint-enable */ /* jshint ignore:start */ + const NUM_MESSAGE_UPGRADES_PER_IDLE = 2; const idleDetector = new IdleDetector(); idleDetector.on('idle', async () => { const results = await MessageDataMigrator.processNext({ BackboneMessage: Whisper.Message, BackboneMessageCollection: Whisper.MessageCollection, - count: 3, + count: NUM_MESSAGE_UPGRADES_PER_IDLE, upgradeMessageSchema, wrapDeferred, }); - console.log('Message schema upgrade:', results); + console.log('Upgrade message schema:', results); if (!results.hasMore) { idleDetector.stop(); diff --git a/js/modules/idle_detector.js b/js/modules/idle_detector.js index 384074ace..9a2ff52b8 100644 --- a/js/modules/idle_detector.js +++ b/js/modules/idle_detector.js @@ -3,7 +3,7 @@ const EventEmitter = require('events'); -const POLL_INTERVAL_MS = 10 * 1000; +const POLL_INTERVAL_MS = 30 * 1000; const IDLE_THRESHOLD_MS = 25; class IdleDetector extends EventEmitter { From f253fef5c6a58055f3e550b40ba26a47733ac30b Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Fri, 23 Mar 2018 10:43:42 -0400 Subject: [PATCH 14/14] Explicitly make `onDestroy` have `void` return type --- js/models/messages.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/models/messages.js b/js/models/messages.js index 1022c1428..624557994 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -148,6 +148,7 @@ this.revokeImageUrl(); const attachments = this.get('attachments'); await Promise.all(attachments.map(deleteAttachmentData)); + return; }, /* jshint ignore:end */ /* eslint-disable */