derbyjs / racer

Realtime model synchronization engine for Node.js
1.18k stars 117 forks source link

Calling `setDiffDeep` from different models can set duplicate data on a given document in a race condition #258

Closed hdavidzhu closed 3 months ago

hdavidzhu commented 5 years ago
const modelA = backend.createModel()
const modelB = backend.createModel()

const $profileInModelA = modelA.at('profiles.profile-id')
const $profileInModelB = modelB.at('profiles.profile-id')

$profileInModelA.fetch((err) => {
  $profileInModelB.fetch((err) => {

  $profileInModelA.set('foo', {bar: []})

    modelA.whenNothingPending(=> {
      modelB.whenNothingPending(=> {

        // These `setDiffDeep`s do not know each other's operations, and would
        // resolve by generating `insert` ops rather than replace on the array.
        // When this is done in quick succession, we set duplicate data
        $profileInModelA.setDiffDeep('foo', {bar: [1,2,3]})
        $profileInModelB.setDiffDeep('foo', {bar: [1,2,3]})

        modelA.whenNothingPending(=> {
          modelB.whenNothingPending(=> {

            $profileInModelA.fetch((err) => {

              console.log($profileInModelA.get('foo.bar'))
              // expect --> [1, 2, 3]
              // result --> [1, 2, 3, 1, 2, 3]
            })
          })
        })
      })
    })
  })
})
craigbeck commented 3 months ago

Thanks for your contributing your issue.

We have recently been actively updating the Derby and Racer packages, and both repos are now in Typescript and published with types on npm. As we have quite a few old issues open we have made the decision to close out of date issues.

If this issue still matters to you we encourage reproducing against the current versions of the repo and opening a new issue.