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

race condition on lazy provider #3494

Closed
1 task
fourdim opened this issue Aug 1, 2023 · 3 comments
Closed
1 task

race condition on lazy provider #3494

fourdim opened this issue Aug 1, 2023 · 3 comments

Comments

@fourdim
Copy link
Contributor

fourdim commented Aug 1, 2023

What happened?

datasource = createDatasource({ dbName, mergeCount });
provider = createLazyProvider(doc, datasource, { origin: 'idb' });
provider.connect();

After call function createIndexedDBProvider, you need to call connect function inside it to connect to it to create a indexeddb.

const createDatasource = ({
dbName,
mergeCount,
}: {
dbName: string;
mergeCount?: number;
}) => {
const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {
upgrade: upgradeDB,
});
const adapter = {
queryDocState: async (guid, options) => {
try {
const db = await dbPromise;
const store = db
.transaction('workspace', 'readonly')
.objectStore('workspace');

However, in the createDatasource function it calls openDB with promise, which can be a race condition.

Distribution version

Web (dev.affine.live)

What browsers are you seeing the problem on if you're using web version?

Firefox

Relevant log output

DOMException: IDBDatabase.transaction: 'workspace' is not a known object store name
    wrapFunction wrap-idb-value.js:150
    queryDocState provider.ts:40
    p lazy-provider.ts:48
    f lazy-provider.ts:134
    C lazy-provider.ts:170
    connect provider.ts:118
    connect indexeddb-provider.ts:19
    syncProviders main.ts:94
    initWorkspace main.ts:127
    main main.ts:152
    <anonymous> main.ts:155

Anything else?

Error is probably caused like this. As they produce the same result in the dev-tools' indexeddb pannel, and raise the same error.

import {
  createIndexedDBProvider,
} from '@toeverything/y-indexeddb';

import { openDB } from 'idb';

import * as Y from 'yjs';

const yDoc = new Y.Doc({
  // we use `guid` as unique key
  guid: 'my-doc',
});

const provider = createIndexedDBProvider(yDoc, 'PLAYGROUND_DB');


(await openDB('PLAYGROUND_DB')).transaction('workspace', 'readwrite')
.objectStore('workspace');

provider.connect();

Are you willing to submit a PR?

  • Yes I'd like to help by submitting a PR!
@pengx17
Copy link
Collaborator

pengx17 commented Aug 3, 2023

Do you know how to reproduce the issue? I think the error DOMException: IDBDatabase.transaction: 'workspace' is not a known object store name in your example is that you need to pass a upgradeDB function like the following to create object store first:

export function upgradeDB(db: IDBPDatabase<BlockSuiteBinaryDB>) {
  db.createObjectStore('workspace', { keyPath: 'id' });
  db.createObjectStore('milestone', { keyPath: 'id' });
}

However I think there is an obvious flaw that if the provider connects twice without disconnect, there could be dangling db connections. 🤔

@fourdim
Copy link
Contributor Author

fourdim commented Aug 3, 2023

To reproduce this issue: open https://blocksuite-toeverything.vercel.app/ in firefox.
The upgrade event is not fired in firefox.

@fourdim
Copy link
Contributor Author

fourdim commented Aug 3, 2023

Closed by toeverything/blocksuite#3824

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

No branches or pull requests

2 participants