Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore doesn't work; store meta info in idb #24

Open
saizai opened this issue Oct 29, 2020 · 1 comment
Open

Restore doesn't work; store meta info in idb #24

saizai opened this issue Oct 29, 2020 · 1 comment

Comments

@saizai
Copy link

saizai commented Oct 29, 2020

If downloads.cache isn't populated (e.g. the extension crashed & was reloaded), then this will fail.

// restore indexdb
{
const restore = async () => {
const os = 'databases' in indexedDB ? await indexedDB.databases() : Object.keys(localStorage)
.filter(name => name.startsWith('file:'))
.map(name => ({
name: name.replace('file:', '')
}));
for (const o of os) {
downloads.download({}, id => {
const {core} = downloads.cache[id];
core.restore(o.name).catch(e => {
console.warn('Cannot restore segments. This database will be removed', e, core);
try {
core.properties.file.remove();
delete downloads.cache[id];
}
catch (e) {}
});
}, undefined, false);
}
};
chrome.runtime.onStartup.addListener(restore);
chrome.runtime.onInstalled.addListener(restore);
}

This could be fixed by adding this to manager.js:

manager.updateDb = (obj) => {
  if (manager.db) {
    const transaction = manager.db.transaction('downloads', 'readwrite');
//    transaction.oncomplete = resolve;
    transaction.onerror = e => reject(Error('Manager.updateDb, ' + e.target.error));
    transaction.objectStore('downloads').put(JSON.parse(JSON.stringify(downloads.cache[obj.id])));
    transaction.commit();
  };
};

{
  request = indexedDB.open('downloads', 1);
  request.onupgradeneeded = () => {
    // TODO - Remove this line when Firefox supports indexedDB.databases()
    if (('databases' in indexedDB) === false) {
      localStorage.setItem('downloads', true);
    }
    request.result.createObjectStore('downloads', {
      keyPath: 'id'
    });
  };
  request.onerror = e => reject(Error('File.open, ' + e.target.error));
  request.onsuccess = () => {
    manager.db = request.result;
    manager.opened = true;
  };
}

downloads.onChanged.addListener(manager.updateDb);

Then one could do something like this at that restore:

req = manager.db.transaction('downloads','readonly').objectStore('downloads').getAll()
req.onSuccess = () => { 
 ...
}

However, the IDB storage necessarily removes functions, callbacks, etc. So downloads.download would need to be refactored to accept this.

@inbasic
Copy link
Owner

inbasic commented Dec 20, 2020

I am not sure how to replicate this. As far as I see, the function does not rely on the existing entries of downloads.cache after a restart. The downloads.download({}, id => {..}) is supposed to prepare a new download entry so the cache must be available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants