From a1929967b364f405c90a002c4963edb913373a44 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Tue, 8 Nov 2016 10:54:26 -0800 Subject: [PATCH] Moved sync directory and sync DB buffering --- {assets => app/assets}/icon.icns | Bin {assets => app/assets}/icon.ico | Bin {assets => app/assets}/install-spinner.gif | Bin app/backend/fetch.js | 2 +- app/backend/util.js | 11 +++++++++++ app/{backend => }/sync/crypt.js | 0 app/{backend => }/sync/index.js | 20 ++++++++++++++------ app/{backend => }/sync/logger.js | 0 app/{backend => }/sync/session.js | 18 ++++++++---------- app/{backend => }/sync/storage.js | 2 +- app/ui/components/RequestPane.js | 2 +- app/ui/components/RequestUrlBar.js | 2 +- app/ui/components/SyncButton.js | 4 ++-- app/ui/components/base/Modal.js | 2 +- app/ui/components/modals/LoginModal.js | 4 ++-- app/ui/components/modals/PaymentModal.js | 2 +- app/ui/components/modals/SettingsModal.js | 4 ++-- app/ui/components/modals/SignupModal.js | 4 ++-- app/ui/components/modals/SyncModal.js | 7 +++---- app/ui/index.js | 4 ++-- app/ui/lib/debounce.js | 11 ----------- scripts/build.sh | 2 +- 22 files changed, 53 insertions(+), 48 deletions(-) rename {assets => app/assets}/icon.icns (100%) rename {assets => app/assets}/icon.ico (100%) rename {assets => app/assets}/install-spinner.gif (100%) rename app/{backend => }/sync/crypt.js (100%) rename app/{backend => }/sync/index.js (98%) rename app/{backend => }/sync/logger.js (100%) rename app/{backend => }/sync/session.js (95%) rename app/{backend => }/sync/storage.js (99%) delete mode 100644 app/ui/lib/debounce.js diff --git a/assets/icon.icns b/app/assets/icon.icns similarity index 100% rename from assets/icon.icns rename to app/assets/icon.icns diff --git a/assets/icon.ico b/app/assets/icon.ico similarity index 100% rename from assets/icon.ico rename to app/assets/icon.ico diff --git a/assets/install-spinner.gif b/app/assets/install-spinner.gif similarity index 100% rename from assets/install-spinner.gif rename to app/assets/install-spinner.gif diff --git a/app/backend/fetch.js b/app/backend/fetch.js index abd5e0d87..0db26f8a5 100644 --- a/app/backend/fetch.js +++ b/app/backend/fetch.js @@ -1,6 +1,6 @@ import {parse as urlParse} from 'url'; import {isDevelopment} from './appInfo'; -import * as session from './sync/session'; +import * as session from '../sync/session'; import * as appInfo from './appInfo'; let commandListeners = []; diff --git a/app/backend/util.js b/app/backend/util.js index e6a51d74e..899a8086f 100644 --- a/app/backend/util.js +++ b/app/backend/util.js @@ -1,5 +1,6 @@ import uuid from 'node-uuid'; import {parse as urlParse, format as urlFormat} from 'url'; +import {DEBOUNCE_MILLIS} from "./constants"; export function getBasicAuthHeader (username, password) { const name = 'Authorization'; @@ -98,3 +99,13 @@ export function delay (milliseconds) { export function removeVowels (str) { return str.replace(/[aeiouyAEIOUY]/g, ''); } + +export function debounce (callback, millis = DEBOUNCE_MILLIS) { + let timeout = null; + return function () { + clearTimeout(timeout); + timeout = setTimeout(() => { + callback.apply(null, arguments) + }, millis); + } +} diff --git a/app/backend/sync/crypt.js b/app/sync/crypt.js similarity index 100% rename from app/backend/sync/crypt.js rename to app/sync/crypt.js diff --git a/app/backend/sync/index.js b/app/sync/index.js similarity index 98% rename from app/backend/sync/index.js rename to app/sync/index.js index eeee19b98..ac6cc4481 100644 --- a/app/backend/sync/index.js +++ b/app/sync/index.js @@ -1,5 +1,5 @@ -import * as db from '../database'; -import * as fetch from '../fetch'; +import * as db from '../backend/database'; +import * as fetch from '../backend/fetch'; import * as crypt from './crypt'; import * as session from './session'; import * as store from './storage'; @@ -136,6 +136,7 @@ export async function pushActiveDirtyResources (resourceGroupId = null) { } // Resolve conflicts + db.bufferChanges(); for (const serverResource of conflicts) { const localResource = await store.getResourceByDocId( serverResource.id, @@ -169,6 +170,7 @@ export async function pushActiveDirtyResources (resourceGroupId = null) { } } } + db.flushChanges(); } export async function pull (resourceGroupId = null, createMissingResources = true) { @@ -226,7 +228,8 @@ export async function pull (resourceGroupId = null, createMissingResources = tru // Insert all the created docs to the DB // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // - await createdResources.map(async serverResource => { + db.bufferChanges(); + for (const serverResource of createdResources) { let doc; try { @@ -252,7 +255,8 @@ export async function pull (resourceGroupId = null, createMissingResources = tru // it's very possible that the client already had that document locally. // This might happen, for example, if the user logs out and back in again. await db.upsert(doc, true); - }); + } + db.flushChanges(); if (createdResources.length) { logger.debug(`Pull created ${createdResources.length} resources`); @@ -262,7 +266,8 @@ export async function pull (resourceGroupId = null, createMissingResources = tru // Save all the updated docs to the DB // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // - await updatedResources.map(async serverResource => { + db.bufferChanges(); + for (const serverResource of updatedResources) { try { const {resourceGroupId, encContent} = serverResource; const doc = await _decryptDoc(resourceGroupId, encContent); @@ -279,7 +284,8 @@ export async function pull (resourceGroupId = null, createMissingResources = tru } catch (e) { logger.warn('Failed to decode updated resource', e, serverResource); } - }); + } + db.flushChanges(); if (updatedResources.length) { logger.debug(`Pull updated ${updatedResources.length} resources`); @@ -289,6 +295,7 @@ export async function pull (resourceGroupId = null, createMissingResources = tru // Remove all the docs that need removing // // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // + db.bufferChanges(); for (const id of idsToRemove) { const resource = await store.getResourceByDocId(id); if (!resource) { @@ -306,6 +313,7 @@ export async function pull (resourceGroupId = null, createMissingResources = tru // Remove from DB await db.remove(doc, true); } + db.flushChanges(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Push all the docs that need pushing // diff --git a/app/backend/sync/logger.js b/app/sync/logger.js similarity index 100% rename from app/backend/sync/logger.js rename to app/sync/logger.js diff --git a/app/backend/sync/session.js b/app/sync/session.js similarity index 95% rename from app/backend/sync/session.js rename to app/sync/session.js index 5ebbb55d2..0aa4dd271 100644 --- a/app/backend/sync/session.js +++ b/app/sync/session.js @@ -1,8 +1,7 @@ import srp from 'srp'; import * as crypt from './crypt'; -import * as util from '../fetch'; -import * as ganalytics from '../ganalytics'; -import {trackEvent} from '../ganalytics'; +import * as util from '../backend/fetch'; +import * as analytics from '../backend/ganalytics'; const NO_SESSION = '__NO_SESSION__'; @@ -47,7 +46,7 @@ export async function signup (firstName, lastName, rawEmail, rawPassphrase) { const response = await util.post('/auth/signup', account); - trackEvent('Session', 'Signup'); + analytics.trackEvent('Session', 'Signup'); return response; } @@ -140,9 +139,8 @@ export async function login (rawEmail, rawPassphrase) { ); // Set the ID for Google Analytics - ganalytics.setAccountId(accountId); - - trackEvent('Session', 'Login'); + analytics.setAccountId(accountId); + analytics.trackEvent('Session', 'Login'); } export async function subscribe (tokenId, planId) { @@ -151,7 +149,7 @@ export async function subscribe (tokenId, planId) { quantity: 1, plan: planId, }); - trackEvent('Session', 'Subscribe', planId, 1); + analytics.trackEvent('Session', 'Subscribe', planId, 1); return response; } @@ -261,7 +259,7 @@ export function isLoggedIn () { export async function logout () { await util.post('/auth/logout'); unsetSessionData(); - trackEvent('Session', 'Logout'); + analytics.trackEvent('Session', 'Logout'); } /** @@ -269,7 +267,7 @@ export async function logout () { */ export async function cancelAccount () { await util.del('/api/billing/subscriptions'); - trackEvent('Session', 'Cancel Account'); + analytics.trackEvent('Session', 'Cancel Account'); } /** diff --git a/app/backend/sync/storage.js b/app/sync/storage.js similarity index 99% rename from app/backend/sync/storage.js rename to app/sync/storage.js index 661014523..12e0c5048 100644 --- a/app/backend/sync/storage.js +++ b/app/sync/storage.js @@ -2,7 +2,7 @@ import electron from 'electron'; import NeDB from 'nedb'; import fsPath from 'path'; import crypto from 'crypto'; -import * as util from '../util'; +import * as util from '../backend/util'; const TYPE_RESOURCE = 'Resource'; const TYPE_CONFIG = 'Config'; diff --git a/app/ui/components/RequestPane.js b/app/ui/components/RequestPane.js index c039b7425..7d6e1527b 100644 --- a/app/ui/components/RequestPane.js +++ b/app/ui/components/RequestPane.js @@ -12,7 +12,7 @@ import { getContentTypeFromHeaders } from '../../backend/contentTypes'; import {MOD_SYM} from '../../backend/constants'; -import {debounce} from '../lib/debounce'; +import {debounce} from '../../backend/util'; class RequestPane extends Component { render () { diff --git a/app/ui/components/RequestUrlBar.js b/app/ui/components/RequestUrlBar.js index 6da968a04..4ec72d2e1 100644 --- a/app/ui/components/RequestUrlBar.js +++ b/app/ui/components/RequestUrlBar.js @@ -56,7 +56,7 @@ class RequestUrlBar extends Component {