From efdeafc8857d8888f7fa0a604376c447a78ad7d9 Mon Sep 17 00:00:00 2001 From: Rik Smith-Unna Date: Sun, 2 Jul 2017 10:31:57 +0300 Subject: [PATCH] Fix race conditions in collection count syncing --- app/client/lib/paper.js | 2 ++ app/client/models/collection.js | 33 +++++++++++++++------------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/client/lib/paper.js b/app/client/lib/paper.js index 5f2f5dd..0b1066e 100644 --- a/app/client/lib/paper.js +++ b/app/client/lib/paper.js @@ -76,6 +76,7 @@ function Paper (data) { self.ds.articlestats(self.files, (err, stats) => { if (err) return cb(err) debug('progress stats', self.title, stats) + if (stats.progress > 0) self.collected = true self.progress = stats.progress * 100 self.progresschecked = true cb(null, self.progress, true) @@ -87,6 +88,7 @@ function Paper (data) { self.download = () => { debug('downloading', self.key) if (self.downloading) return null + self.collected = true self.downloading = true const download = self.ds.download(self) if (!download) return null diff --git a/app/client/models/collection.js b/app/client/models/collection.js index 9c20291..df965e1 100644 --- a/app/client/models/collection.js +++ b/app/client/models/collection.js @@ -1,6 +1,7 @@ const intersection = require('lodash/intersection') const diff = require('lodash/difference') const uniq = require('lodash/uniq') +const debounce = require('lodash/debounce') const isArray = require('lodash/isArray') const batchify = require('byte-stream') const through = require('through2') @@ -31,16 +32,13 @@ module.exports = (state, bus) => { let activescan - const scan = () => { + const _scan = name => { const tags = {} let count = 0 - if (activescan) { - activescan.destroy() - activescan = null - } + if (activescan) return setTimeout(scan, 1000) - let scanstream = activescan = state.collection.docstore.createReadStream().on( + activescan = state.collection.docstore.createReadStream().on( 'data', data => { count += 1 const doc = parsedoc(data.value) @@ -51,7 +49,8 @@ module.exports = (state, bus) => { } ) - eos(scanstream, err => { + eos(activescan, err => { + activescan = null if (err) { if (err.message == 'premature close') { // activescan was destroyed @@ -67,15 +66,16 @@ module.exports = (state, bus) => { restartchecked = true } bus.emit('renderer:render') - activescan = null } }) } + const scan = debounce(_scan, 300, { leading: true, trailing: true }) + require('../lib/localcollection')((err, db) => { if (err) throw err state.collection = db - scan() + scan('initial') }) let activesearches = [] @@ -188,7 +188,6 @@ module.exports = (state, bus) => { const addorupdatepaper = (data, update) => { const papers = isArray(data) ? data : [data] const docs = stream(papers) - const keys = papers.filter(p => !p.collected).map(p => p.key) const index = state.collection @@ -198,27 +197,25 @@ module.exports = (state, bus) => { const maybescan = err => { if (err) throw err - setTimeout(scan, 300) + scan(update ? 'update' : 'add') } - const handleerr = err => { if (err) throw err } + const op = cb => update ? index.update(cb) : index.add(cb) const updatestream = pumpify( docs, metadataify, - update ? index.update() : index.add() + op(maybescan) ) - - eos(updatestream, maybescan) } const updatepaper = data => { const papers = isArray(data) ? data : [data] const oldp = [] const newp = [] - papers.forEach(p => p.collected ? oldp.push(p) : newp.push(p)) + papers.forEach(p => p.progress > 0 ? oldp.push(p) : newp.push(p)) if (oldp.length > 0) addorupdatepaper(oldp, true) - if (newp.length > 0) addorupdatepaper(newp, true) + if (newp.length > 0) addorupdatepaper(newp, false) } const removepaper = data => { @@ -240,7 +237,7 @@ module.exports = (state, bus) => { data.forEach(d => bus.emit('results:remove', d)) bus.emit('selection:clear') bus.emit('detail:toggle') - setTimeout(scan, 300) + scan('remove') }) })