WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 5fdbebd

Browse files
authored
fix: dedupe events (#227)
1 parent 57e4751 commit 5fdbebd

File tree

11 files changed

+5412
-24
lines changed

11 files changed

+5412
-24
lines changed

.npmignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ content
1010
test
1111
.idea/
1212
.github/
13-
.nyc_output/
13+
.nyc_output/

.releaserc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
branches: master

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,5 @@
5454
},
5555
"engines": {
5656
"node": ">=8.16.2"
57-
},
58-
"release": {
59-
"branch": "master"
6057
}
6158
}

src/Feed.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ class Feed {
9191
*/
9292
this.maxHistoryLength; // eslint-disable-line no-unused-expressions
9393

94+
/**
95+
* Track first load failing so skipFirstLoad can be honored on the first passing load
96+
* @type {Boolean}
97+
*/
98+
this.failedFirstLoad = true;
99+
94100
({
95101
items: this.items, url: this.url, refresh: this.refresh, userAgent: this.userAgent,
96102
eventName: this.eventName,
@@ -185,7 +191,9 @@ class Feed {
185191
})
186192
.on('response', (res) => {
187193
if (res.statusCode !== RESPONSE_CODES.OK) {
188-
this.handleError(new FeedError(`This URL returned a ${res.statusCode} status code`, 'fetch_url_error', this.url));
194+
const err = new FeedError(`This URL returned a ${res.statusCode} status code`, 'fetch_url_error', this.url);
195+
Error.captureStackTrace(err);
196+
this.handleError(err);
189197
}
190198
})
191199
.on('error', () => {

src/FeedEmitter.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ class FeedEmitter extends EventEmitter {
9494
* @type {boolean}
9595
*/
9696
this.skipFirstLoad = options.skipFirstLoad;
97+
98+
/**
99+
* Map of emitted event urls grouped by event.
100+
* This is to help prevent overlapping/dupe events in a single event name
101+
* Each entry set clears at the same interval as the most recently applied feed.
102+
* @type {Object}
103+
*/
104+
this.emittedUrlsPerEvent = {};
97105
}
98106

99107
/**
@@ -193,6 +201,14 @@ class FeedEmitter extends EventEmitter {
193201
this.removeFromFeedList(feedInList);
194202
}
195203

204+
if (!this.emittedUrlsPerEvent[feed.eventName]) {
205+
this.emittedUrlsPerEvent[feed.eventName] = {
206+
timeout: setTimeout(() => {
207+
this.emittedUrlsPerEvent[feed.eventName].urls = [];
208+
}, feed.refresh),
209+
urls: [],
210+
};
211+
}
196212
this.addToFeedList(feed);
197213
}
198214

@@ -230,6 +246,7 @@ class FeedEmitter extends EventEmitter {
230246
createSetInterval(feed) {
231247
const feedManager = new FeedManager(this, feed);
232248
feedManager.getContent(true);
249+
233250
return setInterval(feedManager.getContent.bind(feedManager), feed.refresh);
234251
}
235252

@@ -247,6 +264,28 @@ class FeedEmitter extends EventEmitter {
247264
const pos = this.feedList.findIndex((e) => e.url === feed.url);
248265
this.feedList.splice(pos, 1);
249266
}
267+
268+
/**
269+
* Override emit to check if emitted event has already
270+
* been emitted on the same event
271+
* **WARNING:** This is a very limited scope implementation
272+
* If we ever need to emit more than one thing at once, we should expand this
273+
* @param {string} event event name to emit
274+
* @param {Object} data event data/args
275+
* @returns {boolean} [description]
276+
*/
277+
emit(event, data) {
278+
// should only get triggered by initial-load, which we don't want to muck up memory with
279+
if (!this.emittedUrlsPerEvent[event]) {
280+
return super.emit(event, data);
281+
}
282+
283+
if (this.emittedUrlsPerEvent[event].urls.includes(data.link)) {
284+
return false;
285+
}
286+
this.emittedUrlsPerEvent[event].urls.push(data.link);
287+
return super.emit(event, data);
288+
}
250289
}
251290

252291
module.exports = FeedEmitter;

src/FeedManager.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class FeedManager {
8383
populateNewItemsInFeed(data, firstload) {
8484
data.newItems.forEach((item) => {
8585
this.feed.addItem(item);
86-
if (!(firstload && this.instance.skipFirstLoad)) {
86+
if ((firstload && !this.instance.skipFirstLoad) || !firstload) {
8787
this.instance.emit(this.feed.eventName, item);
8888
}
8989
});
@@ -95,6 +95,7 @@ class FeedManager {
9595
* @param {FeedError} error handle error
9696
*/
9797
onError(error) {
98+
console.error(error.stack);
9899
this.instance.emit('error', error);
99100
}
100101

@@ -113,9 +114,13 @@ class FeedManager {
113114
this.feed.updateHxLength(items);
114115
this.sortItemsByDate(data);
115116
this.identifyNewItems(data);
116-
this.populateNewItemsInFeed(data, firstload);
117+
118+
const innerFirst = firstload || (!firstload && this.feed.failedFirstLoad);
119+
120+
this.populateNewItemsInFeed(data, innerFirst);
117121
if (firstload && !this.instance.skipFirstLoad) {
118122
this.instance.emit(`initial-load:${this.feed.url}`, { url: this.feed.url, items: this.feed.items });
123+
this.feed.failedFirstLoad = false;
119124
}
120125
}
121126
}

0 commit comments

Comments
 (0)