dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.5k stars 642 forks source link

Dexie.Observable does not work in service worker #743

Open maksimsemenov opened 6 years ago

maksimsemenov commented 6 years ago

I'm having an issue with Dexie.Observable in service worker.

I'm using `importScripts' to load the modules:

sw.js

importScripts("https://unpkg.com/dexie@2.0.4/dist/dexie.min.js","https://unpkg.com/dexie-observable@1.0.0-beta.4/dist/dexie-observable.min.js");

const actionsDB = new Dexie('linkpt:actions')

actionsDB.version(1).stores({
  actions: `&id`
})

console.log('sw', actionsDB)

actionsDB.on('changes', changes => {
  console.log('sw-actionsDB-changes', Date.now(), changes)
})

I also subscribe on them in the main app code:

import Dexie from 'dexie'
import 'dexie-observable'

export const actionsDB = new Dexie('linkpt:actions')

actionsDB.version(1).stores({
  actions: `&id`
})

actionsDB.on('changes', changes => {
  console.log('actionsDB-changes', Date.now(), changes)
})

When I made some changes in the database, the callback in the main app code gets called, but callback in service-worker doesn't work.

I'm probably doing something wrong, but could not understand what exactly.

dfahlander commented 6 years ago

Dexie.Observable uses storage event to propagate changes across browser frames. This event is not present in workers, so it cannot detect changes as fast. However, it should instead do an interval based polling. Do you see the change event fired but delayed, or is it not fired at all?

maksimsemenov commented 6 years ago

Thanks for the clarification. Unfortunately, the change event in service worker was not fired at all.

dfahlander commented 6 years ago

You also need to import dexie-observable from the sw

dfahlander commented 6 years ago

Sorry, missed that you already do that.

dfahlander commented 6 years ago

The producer must also have dexie-observable imported. For example if your writes occur in a browser window, dexie-observable will make sure the changes are propagated to the _changes table so that the consumer will detect.

If you do import dexie-observable on both the consumer and producer and still have the issue, then this seems to be a bug. The polling should occur every 500ms and the source for that is here.

ttessarolo commented 3 years ago

I've a similar problem. But slightly different.

Im using a Web Worker to fetch data and write to Dexie using bulkPut. And then in the Main App I've an observable to get updates.

To put it shortly:

In the Main App I always open the db as follow (an subscribe to changes):

import Dexie from 'dexie';
import 'dexie-observable';

const   db = new Dexie(dbName);
db.version(dbVersion).stores(dbSchema)
db.on("changes", () => console.log("Change Occurred"));

If in the Web Worker I open the same db of the main app using the following syntax:

import Dexie from 'dexie';
import 'dexie-observable';

const db = await new Dexie(dbName).open();

the changes done in the Web Worker are NOT notified to the Main App.

Otherwise if in the Web Worker I open the db using:

import Dexie from 'dexie';
import 'dexie-observable';

const   db = new Dexie(dbName);
db.version(dbVersion).stores(dbSchema)

The Main App is correctly notified on every change. Missing something?

dfahlander commented 3 years ago

I cannot see why these two syntaxes would do any difference as the db returned via promise from Dexie.open() will be the exact same instance, which would have had observable applied as well. I've noticed that when experimenting with Dexie.Observable you might turn into strange situations when going back and foward between having observable applied and not. Especially, if you happened to open the db without Dexie.Observable on, and then open it with Dexie.Observable applied, it won't be able to apply the new schema unless you update the version no. This might be the case you are seeing the difference.

Just F.Y.I: In Dexie 3.1 there will be a new built-in observability in dexie so you might not need Dexie.Observable. However, you will need to propagate changes between workers and main thread using postMessage to make it react to changes. It will not do any polling of the db as done in Dexie.Observable does. More info about how to do that, with examples, will be provided in the docs quite soon.

PR #1172 contains the update that will be released in Dexie 3.1.

dfahlander commented 3 years ago

In Dexie@3.1.0-alpha.4 you get built-in observability in Dexie including propagation across tabs and workers.

See live example

gotjoshua commented 2 years ago

built-in observability in Dexie including propagation across tabs and workers. @dfahlander

how can a web worker(not a service worker) observe changes that are initiated in the ui?