History

Improve resiliency of IDB database

Thibaut Courouble committed 10 years ago

Commit 80062201 parent a120b882 files · +44 −7Browse files

Unified · Split

2 files
  1. assets/javascripts/app/app.coffee +1 −1
  2. assets/javascripts/app/db.coffee +43 −6
assets/javascripts/app/app.coffee+1−1
@@ -252,7 +252,7 @@ · 251 unmodified lines
252252 false
253253
254254 isSingleDoc: ->
255− !!(@DOC or @doc)
255+ document.body.hasAttribute('data-doc')
256256
257257 isMobile: ->
258258 @_isMobile ?= app.views.Mobile.detect()
assets/javascripts/app/db.coffee+43−6
@@ -25,8 +25,8 @@ class app.DB · 24 unmodified lines
2525 try
2626 db = event.target.result
2727 unless @checkedBuggyIDB
28− @idbTransaction(db, stores: ['docs', app.docs.all()[0].slug], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
2928 @checkedBuggyIDB = true
29+ @idbTransaction(db, stores: $.makeArray(db.objectStoreNames)[0..1], mode: 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937
3030 catch
3131 try db.close()
3232 @reason = 'apple'
@@ -124,11 +124,11 @@ class app.DB · 91 unmodified lines
124124 onError(event)
125125 return
126126
127− store = txn.objectStore(doc.slug)
128− store.clear()
129−
130127 store = txn.objectStore('docs')
131128 store.delete(doc.slug)
129+
130+ store = txn.objectStore(doc.slug)
131+ store.clear()
132132 return
133133 return
134134
@@ -239,9 +239,11 @@ class app.DB · 104 unmodified lines
239239 @cachedDocs = {}
240240
241241 txn = @idbTransaction db, stores: ['docs'], mode: 'readonly'
242− store = txn.objectStore('docs')
242+ txn.oncomplete = =>
243+ setTimeout(@checkForCorruptedDocs, 50)
244+ return
243245
244− req = store.openCursor()
246+ req = txn.objectStore('docs').openCursor()
245247 req.onsuccess = (event) =>
246248 return unless cursor = event.target.result
247249 @cachedDocs[cursor.key] = cursor.value
@@ -252,6 +254,41 @@ class app.DB · 4 unmodified lines
252254 return
253255 return
254256
257+ checkForCorruptedDocs: =>
258+ @db (db) =>
259+ @corruptedDocs = []
260+ docs = (key for key, value of @cachedDocs when value)
261+ return if docs.length is 0
262+
263+ for slug in docs when not app.docs.findBy('slug', slug)
264+ @corruptedDocs.push(slug)
265+
266+ for slug in @corruptedDocs
267+ $.arrayDelete(docs, slug)
268+
269+ txn = @idbTransaction(db, stores: docs, mode: 'readonly', ignoreError: false)
270+ txn.oncomplete = =>
271+ setTimeout(@deleteCorruptedDocs, 0) if @corruptedDocs.length > 0
272+ return
273+
274+ for doc in docs
275+ txn.objectStore(doc).get('index').onsuccess = (event) =>
276+ @corruptedDocs.push(event.target.source.name) unless event.target.result
277+ return
278+ return
279+ return
280+
281+ deleteCorruptedDocs: =>
282+ @db (db) =>
283+ txn = @idbTransaction(db, stores: ['docs'], mode: 'readwrite', ignoreError: false)
284+ store = txn.objectStore('docs')
285+ while doc = @corruptedDocs.pop()
286+ @cachedDocs[doc] = false
287+ store.delete(doc)
288+ return
289+ Raven.captureMessage 'corruptedDocs', extra: { docs: @corruptedDocs.join(',') }
290+ return
291+
255292 shouldLoadWithIDB: (entry) ->
256293 @useIndexedDB and (not @cachedDocs or @cachedDocs[entry.doc.slug])
257294