Skip to content

Commit

Permalink
Background listener cleanup (#3040)
Browse files Browse the repository at this point in the history
* rename environment/_helpers.js -> environment/_messaging.js

* environment: move duplicated background listeners to environment/_common.js

* Cache subclasses Map
  • Loading branch information
erikdesjardins committed Jun 2, 2016
1 parent d5022c1 commit 6d8fadc
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 148 deletions.
41 changes: 4 additions & 37 deletions chrome/background.entry.js
Expand Up @@ -30,8 +30,8 @@
*/

import { createMessageHandler } from '../lib/environment/_helpers';
import Cache from '../lib/utils/Cache';
import { addCommonBackgroundListeners } from '../lib/environment/_common';
import { createMessageHandler } from '../lib/environment/_messaging';

import cssOff from './images/css-off.png';
import cssOffSmall from './images/css-off-small.png';
Expand Down Expand Up @@ -60,6 +60,8 @@ chrome.runtime.onMessage.addListener(({ type, ...obj }, sender, sendResponse) =>

// Listeners

addCommonBackgroundListeners(addListener);

addListener('ajax', async ({ method, url, headers, data, credentials }) => {
const request = new XMLHttpRequest();

Expand Down Expand Up @@ -127,24 +129,6 @@ addListener('permissions', async ({ operation, permissions, origins }, { id: tab
}
})();

const session = new Map();

addListener('session', ([operation, key, value]) => {
switch (operation) {
case 'get':
return session.get(key);
case 'set':
session.set(key, value);
break;
case 'delete':
return session.delete(key);
case 'clear':
return session.clear();
default:
throw new Error(`Invalid session operation: ${operation}`);
}
});

addListener('deleteCookies', cookies =>
cookies.forEach(({ url, name }) => chrome.cookies.remove({ url, name }))
);
Expand All @@ -162,23 +146,6 @@ addListener('addURLToHistory', url => {
chrome.history.addUrl({ url });
});

const cache = new Cache();

addListener('XHRCache', ({ operation, key, value, maxAge }) => {
switch (operation) {
case 'set':
return cache.set(key, value);
case 'check':
return cache.check(key, maxAge);
case 'delete':
return cache.delete(key);
case 'clear':
return cache.clear();
default:
throw new Error(`Invalid XHRCache operation: ${operation}`);
}
});

chrome.pageAction.onClicked.addListener(({ id: tabId }) =>
sendMessage('pageActionClick', undefined, { tabId })
);
Expand Down
2 changes: 1 addition & 1 deletion chrome/environment.js
@@ -1,4 +1,4 @@
import { createMessageHandler } from '../lib/environment/_helpers';
import { createMessageHandler } from '../lib/environment/_messaging';
import { extendDeep, keyedMutex, waitForEvent } from '../lib/utils';
import { apiToPromise } from './_helpers';

Expand Down
41 changes: 4 additions & 37 deletions firefox/background.entry.js
@@ -1,9 +1,9 @@
import mainEntry from '../lib/main.entry'; // eslint-disable-line import/default
import resCss from '../lib/css/res.scss';

import { createMessageHandler } from '../lib/environment/_helpers';
import { addCommonBackgroundListeners } from '../lib/environment/_common';
import { createMessageHandler } from '../lib/environment/_messaging';
import { nativeRequire } from '../lib/environment/_nativeRequire';
import Cache from '../lib/utils/Cache';
import { extendDeep } from '../lib/utils/object';

import cssDisabled from './images/css-disabled.png';
Expand Down Expand Up @@ -67,6 +67,8 @@ const {

// Listeners

addCommonBackgroundListeners(addListener);

addListener('deleteCookies', cookies =>
cookies.forEach(({ name }) => cookieManager.remove('.reddit.com', name, '/', false, false))
);
Expand Down Expand Up @@ -236,41 +238,6 @@ addListener('storage', ([operation, key, value]) => {
}
});

const session = new Map();

addListener('session', ([operation, key, value]) => {
switch (operation) {
case 'get':
return session.get(key);
case 'set':
session.set(key, value);
break;
case 'delete':
return session.delete(key);
case 'clear':
return session.clear();
default:
throw new Error(`Invalid session operation: ${operation}`);
}
});

const cache = new Cache();

addListener('XHRCache', ({ operation, key, value, maxAge }) => {
switch (operation) {
case 'set':
return cache.set(key, value);
case 'check':
return cache.check(key, maxAge);
case 'delete':
return cache.delete(key);
case 'clear':
return cache.clear();
default:
throw new Error(`Invalid XHRCache operation: ${operation}`);
}
});

const pageAction = ActionButton({
id: 'res-styletoggle',
label: 'toggle subreddit CSS',
Expand Down
2 changes: 1 addition & 1 deletion firefox/environment.js
@@ -1,4 +1,4 @@
import { createMessageHandler } from '../lib/environment/_helpers';
import { createMessageHandler } from '../lib/environment/_messaging';

const {
_handleMessage,
Expand Down
38 changes: 38 additions & 0 deletions lib/environment/_common.js
@@ -0,0 +1,38 @@
import Cache from '../utils/Cache';

export function addCommonBackgroundListeners(addListener) {
const session = new Map();

addListener('session', ([operation, key, value]) => {
switch (operation) {
case 'get':
return session.get(key);
case 'set':
session.set(key, value);
break;
case 'delete':
return session.delete(key);
case 'clear':
return session.clear();
default:
throw new Error(`Invalid session operation: ${operation}`);
}
});

const cache = new Cache();

addListener('XHRCache', ([operation, key, value]) => {
switch (operation) {
case 'set':
return cache.set(key, value);
case 'check':
return cache.get(key, value);
case 'delete':
return cache.delete(key);
case 'clear':
return cache.clear();
default:
throw new Error(`Invalid XHRCache operation: ${operation}`);
}
});
}
File renamed without changes.
8 changes: 4 additions & 4 deletions lib/environment/xhrCache.js
Expand Up @@ -6,7 +6,7 @@ import { sendMessage } from 'browserEnvironment';
* @returns {Promise<void, *>}
*/
export function set(key, value) {
return sendMessage('XHRCache', { operation: 'set', key, value });
return sendMessage('XHRCache', ['set', key, value]);
}

/**
Expand All @@ -15,21 +15,21 @@ export function set(key, value) {
* @returns {Promise<*|void, *>}
*/
export function check(key, maxAge) {
return sendMessage('XHRCache', { operation: 'check', key, maxAge });
return sendMessage('XHRCache', ['check', key, maxAge]);
}

/**
* @param {string} key
* @returns {Promise<void, *>}
*/
export function _delete(key) {
return sendMessage('XHRCache', { operation: 'delete', key });
return sendMessage('XHRCache', ['delete', key]);
}
export { _delete as delete };

/**
* @returns {Promise<void, *>}
*/
export function clear() {
return sendMessage('XHRCache', { operation: 'clear' });
return sendMessage('XHRCache', ['clear']);
}
42 changes: 13 additions & 29 deletions lib/utils/Cache.js
@@ -1,43 +1,27 @@
export default class Cache {
entries = new Map();

constructor(capacity = 250) {
export default class Cache extends Map {
constructor(capacity = 500) {
super();
this.capacity = capacity;
}

check(key, maxAge = Infinity) {
const entry = this.entries.get(key);
get(key, maxAge = Infinity) {
const entry = super.get(key);
const now = Date.now();
if (entry && (now - entry.timestamp < maxAge)) {
entry.timestamp = now;
return entry.data;
return entry.value;
}
}

set(key, value) {
this.entries.set(key, {
data: value,
timestamp: Date.now(),
});
super.set(key, { value, timestamp: Date.now() });

if (this.entries.size > this.capacity) {
this._prune();
if (this.size > this.capacity) {
// evict least-recently used
Array.from(this.entries())
.sort(([, a], [, b]) => b.timestamp - a.timestamp)
.slice((this.capacity / 2) | 0)
.forEach(([key]) => this.delete(key));
}
}

delete(key) {
this.entries.delete(key);
}

clear() {
this.entries.clear();
}

_prune() {
// evict least-recently used
Array.from(this.entries.entries())
.sort(([, a], [, b]) => b.timestamp - a.timestamp)
.slice((this.capacity / 2) | 0)
.forEach(([key]) => this.entries.delete(key));
}
}
2 changes: 1 addition & 1 deletion node/environment.js
@@ -1,4 +1,4 @@
import { createMessageHandler } from '../lib/environment/_helpers';
import { createMessageHandler } from '../lib/environment/_messaging';
import { extendDeep } from '../lib/utils';

const {
Expand Down
41 changes: 4 additions & 37 deletions safari/background.entry.js
Expand Up @@ -2,8 +2,8 @@

import 'babel-polyfill';

import { createMessageHandler } from '../lib/environment/_helpers';
import Cache from '../lib/utils/Cache';
import { addCommonBackgroundListeners } from '../lib/environment/_common';
import { createMessageHandler } from '../lib/environment/_messaging';
import { extendDeep } from '../lib/utils/object';

const {
Expand All @@ -18,6 +18,8 @@ safari.application.addEventListener('message', ({ name: type, message: obj, targ

// Listeners

addCommonBackgroundListeners(addListener);

addListener('ajax', async ({ method, url, headers, data, credentials }) => {
const request = new XMLHttpRequest();

Expand Down Expand Up @@ -105,24 +107,6 @@ addListener('storage', ([operation, key, value]) => {
}
});

const session = new Map();

addListener('session', ([operation, key, value]) => {
switch (operation) {
case 'get':
return session.get(key);
case 'set':
session.set(key, value);
break;
case 'delete':
return session.delete(key);
case 'clear':
return session.clear();
default:
throw new Error(`Invalid session operation: ${operation}`);
}
});

addListener('openNewTabs', ({ urls, focusIndex }, tab) => {
// Really? No SafariBrowserTab::index?
let currentIndex = Array.from(tab.browserWindow.tabs).findIndex(t => t === tab);
Expand All @@ -135,23 +119,6 @@ addListener('openNewTabs', ({ urls, focusIndex }, tab) => {
));
});

const cache = new Cache();

addListener('XHRCache', ({ operation, key, value, maxAge }) => {
switch (operation) {
case 'set':
return cache.set(key, value);
case 'check':
return cache.check(key, maxAge);
case 'delete':
return cache.delete(key);
case 'clear':
return cache.clear();
default:
throw new Error(`Invalid XHRCache operation: ${operation}`);
}
});

addListener('isPrivateBrowsing', (request, tab) => tab.private);

addListener('multicast', async (request, senderTab) =>
Expand Down
2 changes: 1 addition & 1 deletion safari/environment.js
Expand Up @@ -4,7 +4,7 @@ import 'babel-polyfill';

import resCss from '../lib/css/res.scss';

import { createMessageHandler } from '../lib/environment/_helpers';
import { createMessageHandler } from '../lib/environment/_messaging';
import { nonNull } from '../lib/utils';

// Safari has a ridiculous bug that causes it to lose access to safari.self.tab if you click the back button.
Expand Down

0 comments on commit 6d8fadc

Please sign in to comment.