Handle empty subscription queue and OOP-ify

This commit is contained in:
Cadence Ember 2020-10-03 01:32:22 +13:00
parent 830c009066
commit 1ea272600c
No known key found for this signature in database
GPG Key ID: BC1C2C61CF521B17
3 changed files with 67 additions and 31 deletions

View File

@ -3,6 +3,7 @@ const db = require("../utils/db")
const {fetchChannelLatest} = require("../utils/youtube") const {fetchChannelLatest} = require("../utils/youtube")
const {getUser} = require("../utils/getuser") const {getUser} = require("../utils/getuser")
const {timeToPastText} = require("../utils/converters") const {timeToPastText} = require("../utils/converters")
const {refresher} = require("../background/feed-update")
module.exports = [ module.exports = [
{ {
@ -13,6 +14,8 @@ module.exports = [
let channels = [] let channels = []
let refreshed = null let refreshed = null
if (user.token) { if (user.token) {
// trigger a background refresh, needed if they came back from being inactive
refresher.skipWaiting()
// get channels // get channels
const subscriptions = user.getSubscriptions() const subscriptions = user.getSubscriptions()
const template = Array(subscriptions.length).fill("?").join(", ") const template = Array(subscriptions.length).fill("?").join(", ")

View File

@ -61,43 +61,68 @@ class RefreshQueue {
} }
} }
const refreshQueue = new RefreshQueue() class Refresher {
constructor() {
this.sym = constants.symbols.refresher
this.refreshQueue = new RefreshQueue()
this.state = this.sym.ACTIVE
this.waitingTimeout = null
this.next()
}
function refreshChannel(ucid) { refreshChannel(ucid) {
return fetch(`http://localhost:3000/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(root => { return fetch(`http://localhost:3000/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(root => {
if (Array.isArray(root)) { if (Array.isArray(root)) {
root.forEach(video => { root.forEach(video => {
// organise // organise
video.descriptionHtml = video.descriptionHtml.replace(/<a /g, '<a tabindex="-1" ') // should be safe video.descriptionHtml = video.descriptionHtml.replace(/<a /g, '<a tabindex="-1" ') // should be safe
video.viewCountText = null //TODO? video.viewCountText = null //TODO?
// store // store
prepared.video_insert.run(video) prepared.video_insert.run(video)
}) })
// update channel refreshed // update channel refreshed
prepared.channel_refreshed_update.run(Date.now(), ucid) prepared.channel_refreshed_update.run(Date.now(), ucid)
console.log(`updated ${root.length} videos for channel ${ucid}`) console.log(`updated ${root.length} videos for channel ${ucid}`)
} else if (root.identifier === "PUBLISHED_DATES_NOT_PROVIDED") { } else if (root.identifier === "PUBLISHED_DATES_NOT_PROVIDED") {
return [] // nothing we can do. skip this iteration. return [] // nothing we can do. skip this iteration.
} else { } else {
throw new Error(root.error) throw new Error(root.error)
}
})
}
next() {
if (this.refreshQueue.isEmpty()) {
const timeSinceLastLoop = Date.now() - this.refreshQueue.lastLoadTime
if (timeSinceLastLoop < constants.caching.subscriptions_refresh_loop_min) {
const timeToWait = constants.caching.subscriptions_refresh_loop_min - timeSinceLastLoop
console.log(`waiting ${timeToWait} before next loop`)
this.state = this.sym.WAITING
this.waitingTimeout = setTimeout(() => this.next(), timeToWait)
return
} else {
this.refreshQueue.load()
}
} }
})
}
function refreshNext() { if (!this.refreshQueue.isEmpty()) {
if (refreshQueue.isEmpty()) { this.state = this.sym.ACTIVE
const timeSinceLastLoop = Date.now() - refreshQueue.lastLoadTime const ucid = this.refreshQueue.next()
if (timeSinceLastLoop < constants.caching.subscriptions_refresh_loop_min) { this.refreshChannel(ucid).then(() => this.next())
const timeToWait = constants.caching.subscriptions_refresh_loop_min - timeSinceLastLoop
console.log(`waiting ${timeToWait} before next loop`)
return setTimeout(refreshNext, timeToWait)
} else { } else {
refreshQueue.load() this.state = this.sym.EMPTY
} }
} }
const ucid = refreshQueue.next() skipWaiting() {
refreshChannel(ucid).then(refreshNext) if (this.state !== this.sym.ACTIVE) {
clearTimeout(this.waitingTimeout)
this.refreshQueue.lastLoadTime = 0
this.next()
}
}
} }
refreshNext() const refresher = new Refresher()
module.exports.refresher = refresher

View File

@ -19,6 +19,14 @@ const constants = {
regex: { regex: {
ucid: "[A-Za-z0-9-_]+", ucid: "[A-Za-z0-9-_]+",
video_id: "[A-Za-z0-9-_]+" video_id: "[A-Za-z0-9-_]+"
},
symbols: {
refresher: {
ACTIVE: Symbol("ACTIVE"),
WAITING: Symbol("WAITING"),
EMPTY: Symbol("EMPTY")
}
} }
} }