pubkey / rxdb

A fast, local first, reactive Database for JavaScript Applications https://rxdb.info/
https://rxdb.info/
Apache License 2.0
21.12k stars 1.03k forks source link

[bug] Deleting all items with a sorted subscribe throws error #393

Closed natew closed 6 years ago

natew commented 6 years ago

Case

Need to narrow this down a bit better as it happens in a complex area. Basic gist of it is this:

Thing.find()
          .limit(8)
          .where('bucket')
          .eq(CurrentUser.bucket)
          .sort({ updatedAt: 'desc' })
  .subscribe(x => {
    console.log(x)
  })

Issue

When you delete all entries like so:

async function destroyAll(collection) {
      const remove = async item => {
        try {
          await item.remove()
        } catch (e) {
          // loop on document conflicts to delete all revisions
          console.log('err', e)
          await remove(item)
        }
        return true
      }
      const all = await collection.find()
      if (!all) {
        return
      }
      return await Promise.all(all.map(remove))
}

You get this:

TypeError: Cannot convert undefined or null to object
    at Function.entries (<anonymous>)
    at RxSchema.swapPrimaryToId (http://app.seemirai.com:3001/_/bundle.1.js:110105:14)
    at QueryChangeDetector._isSortedBefore (http://app.seemirai.com:3001/_/bundle.1.js:109248:53)
    at sortAfter (http://app.seemirai.com:3001/_/bundle.1.js:109067:54)
    at QueryChangeDetector.handleSingleChange (http://app.seemirai.com:3001/_/bundle.1.js:109121:46)
    at http://app.seemirai.com:3001/_/bundle.1.js:109010:25
    at Array.find (native)
    at QueryChangeDetector.runChangeDetection (http://app.seemirai.com:3001/_/bundle.1.js:109009:32)
    at RxQuery._callee$ (http://app.seemirai.com:3001/_/bundle.1.js:107881:58)
    at tryCatch (http://app.seemirai.com:3001/_/bundle.1.js:87830:40)

I can reproduce it by having a function that clears all things and re-creates them again. Let me know if this doesn't ring any bells I can get a better sourcemap / schema / etc.

pubkey commented 6 years ago

Hm strange. Looks like this has something to do with the primary-key. Please post your schema.

natew commented 6 years ago
{
  "primaryPath": "_id",
  "disableKeyCompression": true,
  "properties": {
    "id": {
      "primary": true,
      "type": "string"
    },
    "title": {
      "index": true,
      "type": "string"
    },
    "integration": {
      "type": "string"
    },
    "type": {
      "index": true,
      "type": "string"
    },
    "bodyTEMP": {
      "type": "string"
    },
    "data": {
      "type": "object"
    },
    "parentId": {
      "type": "string"
    },
    "author": {
      "type": "string"
    },
    "created": {
      "index": true,
      "type": "string"
    },
    "updated": {
      "index": true,
      "type": "string"
    },
    "orgName": {
      "type": "string"
    },
    "bucket": {
      "type": "string"
    },
    "url": {
      "unique": true,
      "type": "string"
    },
    "createdAt": {
      "format": "date-time",
      "type": "string",
      "index": true
    },
    "updatedAt": {
      "format": "date-time",
      "type": "string",
      "index": true
    }
  },
  "type": "object",
  "required": [
    "title",
    "integration",
    "type",
    "created",
    "updated"
  ],
  "title": "things",
  "version": 0
}
natew commented 6 years ago

Testing this in browser and I haven't triggered it after a few tries now.

Weirdly though I'm not seeing .remove() sync across tabs until refresh. Insert seems to sync just fine.

I should have noted I'm not on the latest RxDB, using 6.0.1 until I get a chance to fix bundling on 7.

pubkey commented 6 years ago

Can you disable the QueryChangeDetector and check if it works then?

natew commented 6 years ago

Ah good point.

Test results from that:

Chrome + QueryChangeDetector = Delete doesn't propogate across tabs (insert does) Electron + QueryChangeDetector = Delete throws error above (with sort)

Disabled querychange and now:

Electron seems to be fine, the bug above isn't replicating. Browser was working for a moment where remove and update were fine, but now:

Re-enabled it and the first electron bug went away, so not sure whats going on there. Second delete sync issue is still there:

https://v.usetapes.com/y0DbIRQuVs

The document conflict seems interesting, perhaps I'm not clearing them properly all the way. Double checking that...

pubkey commented 6 years ago

I tried to reproduce. One thing: You have an error in the code

const all = await collection.find() should be const all = await collection.find().exec()

pubkey commented 6 years ago

Hi @natew I'm sorry but I won't fix this. I spend much time to reproduce and fix this, but I can't. I basically comes down to the following problem: When you create multiple pouchdb-instances on the same adapter and then do many deletes on one instance while at the same time doing many queries on the other instance, it breaks. I also created a branch for this issue and created this test which shows what does not work on plain pouchdb-instances.

This is a pouchdb-issue and should be solved there. I think there is a way to monkeypatch this on rxdb, but there is still a missing way to reproduce the error you got on the linked video. (The test produces another, but similar error).

It would be nice if you have the time to create a failing test which creates your specific error.