derbyjs / racer

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

Fix memory leak when unfetching doc with pending ops #276

Closed ericyhwang closed 4 years ago

ericyhwang commented 4 years ago

Commit https://github.com/derbyjs/racer/commit/a6374765621745d3e76977b8483e4263ba4a61c5 (PR https://github.com/derbyjs/racer/pull/265 / https://github.com/derbyjs/racer/pull/266) introduced a memory leak when calling unfetch() on a doc that has pending or inflight ops.

Previously, the doc would be immediately unloaded in that scenario, freeing it up for garbage collection. That commit added a check for the ShareDB Doc#hasPending(), which means that the doc no longer gets unloaded at all in that situation.

This PR fixes the memory leak regression. Now, in the situation where unfetch() is called on a doc that has pending or inflight ops, then instead of exiting early, _maybeUnloadDoc() will do a ShareDoc#whenNothingPending to schedule the unload after the docs has nothing else pending.


For reference, the newly added test fails like this without the new fix:

  1) loading
       unfetch
         unloads doc after Share doc has nothing pending:
     Uncaught Error: expected { hex: '00ee00', id: 'green' } to equal undefined
      at Assertion.assert (node_modules/expect.js/index.js:96:13)
      at Assertion.be.Assertion.equal (node_modules/expect.js/index.js:216:10)
      at /Users/ehwang/lever/derbyjs/racer/test/Model/loading.js:66:50
      at process._tickCallback (internal/process/next_tick.js:61:11)
ericyhwang commented 4 years ago

Fix published in racer@0.9.12