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

PrematureCommitError: Transaction committed too early on addCollections() #6008

Open
Mike-FR opened this issue May 16, 2024 · 6 comments
Open

Comments

@Mike-FR
Copy link

Mike-FR commented May 16, 2024

Hello,
I was using rxdb 14 on a Vue 2.7 project without problems. I updated rxdb to version 15 and since then I'm facing a PrematureCommitError" error when doing addCollections().
I tried several things without success so I redid a basic implementation on an internal test repository which runs on Vue 3. Same error.
Here is the code on my test repo.

import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import i18n from "./setup/i18n";
import createVuetify from "./setup/vuetify";
import SocioManifest from "../socio-manifest.json";
import PackageJson from "../package.json";
import SocioVueComponents, {
  initializeTracingAndLogging,
} from "@socotec.io/socio-vue-components";

import { addRxPlugin } from 'rxdb';
import { createRxDatabase } from 'rxdb';
import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';
import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';

addRxPlugin(RxDBDevModePlugin);

initializeTracingAndLogging(SocioManifest, PackageJson, { router });

const createDatabase = async () => {
  const myDatabase = await createRxDatabase({
    name: 'mydatabase',
    storage: getRxStorageDexie()
  });
  
  const todoSchema = {
      version: 0,
      primaryKey: 'id',
      type: 'object',
      properties: {
          id: {
              type: 'string',
              maxLength: 100 // <- the primary key must have set maxLength
          },
          name: {
              type: 'string'
          },
          done: {
              type: 'boolean'
          },
          timestamp: {
              type: 'string',
              format: 'date-time'
          }
      },
      required: ['id', 'name', 'done', 'timestamp']
    }
    
    await myDatabase.addCollections({
      todos: {
        schema: todoSchema
      }
    });

    return {
      install(app) {
        app.provide(myDatabase);
      },
    };
  }

const db = createDatabase()

const app = createApp(App);

app.use(router);
app.use(store);
app.use(i18n);
app.use(createVuetify(i18n));
app.use(SocioVueComponents, i18n);

db.then(database => {
  app.use(database).mount('#app');
});

my package.json if it helps

{
  "name": "test-infra-front",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "serve": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
    "lint:fix": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --ignore-path .gitignore --fix",
    "format": "prettier --write . --ignore-path .gitignore"
  },
  "dependencies": {
    "@bufbuild/protobuf": "^1.7.2",
    "@connectrpc/connect": "^1.3.0",
    "@connectrpc/connect-web": "^1.3.0",
    "@intlify/unplugin-vue-i18n": "^2.0.0",
    "@socotec.io/socio-grpc-api": "^776.0.7",
    "@socotec.io/socio-vue-components": "vue3",
    "@vue/compat": "^3.4.16",
    "@vuex-orm/core": "^0.36.4",
    "axios": "^1.3.0",
    "core-js": "^3.35.0",
    "oidc-client": "^1.11.5",
    "rxdb": "^15.20.0",
    "rxjs": "^7.8.1",
    "vite-plugin-vuetify": "^2.0.1",
    "vue": "^3.3.11",
    "vue-i18n": "^9.8.0",
    "vue-router": "^4.2.5",
    "vuetify": "^3.4.10",
    "vuex": "^4.0.2",
    "vuex-oidc": "^3.10.1"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.3.3",
    "@vitejs/plugin-vue": "^4.5.2",
    "@vue/eslint-config-prettier": "^8.0.0",
    "eslint": "^8.49.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.2",
    "eslint-plugin-vue": "^9.19.2",
    "eslint-plugin-vuetify": "^2.1.1",
    "lint-staged": "^15.2.0",
    "prettier": "^3.0.3",
    "sass": "^1.69.7",
    "terser": "^5.27.0",
    "vite": "^5.0.10",
    "yorkie": "^2.0.0"
  },
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,vue}": [
      "yarn lint",
      "yarn format",
      "git add ."
    ]
  }
}

The error inside the console that appears immediately
image

The IndexexDB look likes
image

Do you see an implementation error? Thanks for your help.

@AMontagu
Copy link

To add more informations while debugging (I am working with @Mike-FR )

The code that emit exception start here: https://github.com/pubkey/rxdb/blob/master/src/rx-database.ts#L351

The bulkWrite funciton is called first time with internal-add-storage-token and second time with rx-database-add-collection that is the one we are interested in.

The devMode is True.

The scopeFuncIsAsync is True.

The transaction code run without issue but when it try to commit it directly send to: https://github.com/dexie/Dexie.js/blob/a5519e58e407c518cb47c10673fc8c2fe585a389/src/classes/dexie/transaction-helpers.ts#L99

So IMO there is something between https://github.com/pubkey/rxdb/blob/master/src/plugins/storage-dexie/rx-storage-instance-dexie.ts#L148 and https://github.com/pubkey/rxdb/blob/master/src/plugins/storage-dexie/rx-storage-instance-dexie.ts#L202

that do not respect Dexie rule: https://dexie.org/docs/DexieErrors/Dexie.PrematureCommitError.html

@AMontagu
Copy link

By looking more the issue probably come from incrementExpectedAwaits or decrementExpectedAwaits.
https://github.com/dexie/Dexie.js/blob/master/src/helpers/promise.js#L597
https://github.com/dexie/Dexie.js/blob/master/src/helpers/promise.js#L607

Meaning that we may have some other dependecy changing the default behavior of async/await.
We will try to go with an empty vue/vite project. Then if not working an empty vanilla project.

@Mike-FR
Copy link
Author

Mike-FR commented May 16, 2024

I identified that the problem comes from the zone.js package and in our case it is itself installed by @opentelemetry/context-zone itself installed by @grafana/faro-web-tracing that we use in our Vue frontend.

@AMontagu
Copy link

Look like: #6011

Is that mean we need to wait for faro to update dependencies of zone js ?

Copy link

stale bot commented May 24, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon. Please update it or it may be closed to keep our repository organized. The best way is to add some more information or make a pull request with a test case. Also you might get help in fixing it at the RxDB Community Chat If you know you will continue working on this, just write any message to the issue (like "ping") to remove the stale tag.

@stale stale bot added the stale label May 24, 2024
@Mike-FR
Copy link
Author

Mike-FR commented May 27, 2024

ping

@stale stale bot removed the stale label May 27, 2024
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