ramiel / mongoose-sequence

Sequence and autoincrement handling for mongoose
GNU General Public License v2.0
284 stars 56 forks source link

sequence not counting on cosmosDB #117

Open sghoe opened 2 years ago

sghoe commented 2 years ago

Hello, thank you for this nice middleware.

We switched from mongoDB to cosmosDB but it stopped counting. The counters were created, but the seq. stays and remains at 1.

Now we are on:

"mongoose": "^6.1.6",
"mongoose-sequence": "^5.3.1",

Is sequence compatible with cosmosDB?

ramiel commented 2 years ago

To be honest, I don't know. I never tried it on CosmosDB. There's nothing special in this middleware, so as long as basic operations on mongo are supported on cosmos, it should work. I can't tell you more, sorry

sghoe commented 2 years ago

hello ramiel, thank you for your quick response.

While debugging it seems that every time the lastErrorObject.updatedExisting is false at the counter and it puts in the startSeq everytime

// lastErrorObject.updatedExisting is true if new entry was upserted if (_.has(counter, 'lastErrorObject') && !counter.lastErrorObject.updatedExisting) { return callback(null, startSeq); }

we are using "mongoose": "5.13.14",

do you have any additional ideas?

perfusorius commented 2 years ago

Hello @sghoe , Hello @ramiel

I also have this issue. My app was using MongoDB in MongoCloud and everything was working as expected. But a switch to Azure CosmosDB was neccessary and suddenly mongoose-sequence stopped working.

Through local debugging and testing I found the cause(s) and how to fix them.

Cosmos/Mongo will prevent inserting and updating of Counters documents when the uniqueness check in the defined index is in place. So changing (line 200)

    CounterSchema.index({ id: 1, reference_value: 1 }, { unique: true });

to

    CounterSchema.index({ id: 1, reference_value: 1 });

is the first step. Since you already use upserts with filtering for id and reference_value uniqueness of all documents should still be given.

As @sghoe mentions in the above comment in the callback in Sequence.prototype._createCounter always startSeq is returned to the callback. When the upsert was successful then counter object in that callback has a property lastErrorObject, and a property value that contains the created document. That means it did work and in that case, according to how I understood your logic, the callback that is then called should get null as its second parameter instead of startSeq. So my second proposal would be to change (lines 389 ff.)

        if (_.has(counter, 'lastErrorObject') && !counter.lastErrorObject.updatedExisting) {
          return callback(null, startSeq);
        }

to

        if ('value' in counter && 'seq' in counter.value) {
          return callback(null, null);
        }
        else if (_.has(counter, 'lastErrorObject') && !counter.lastErrorObject.updatedExisting) {
          return callback(null, startSeq);
        }

With these two changes I could get my app to work with CosmosDB. Counter-documents where created again as expected and seqvalues were increased correctly for each new document in the watched collections.