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

Add option to disable prewrite hook #60

Open
vweevers opened this issue Nov 20, 2022 · 2 comments
Open

Add option to disable prewrite hook #60

vweevers opened this issue Nov 20, 2022 · 2 comments
Labels
enhancement New feature or request

Comments

@vweevers
Copy link
Member

Context

I'm working on a rewrite of level-ttl, not because I need it, but to make it use hooks and find out what gaps we in that API.

Problem

If a plugin like level-ttl uses the prewrite hook but also has a background job that writes to the same db, it will trigger its own hook function (as well as other hook functions). E.g.:

module.exports = function ttl (db) {
  // Imagine a sublevel to which we write expiry metadata
  const sublevel = ...

  db.hooks.prewrite.add(function (op, batch) {
    if (op.type === 'put') {
      const exp = Date.now() + op.ttl
      batch.add({ type: 'put', sublevel, key: op.key, value: exp })
    } else {
      batch.add({ type: 'del', sublevel, key: op.key })
    }
  })

  // Background job
  setInterval(function sweep () {
    // Imagine we're deleting an expired key
    db.del('foo').catch(..)
  }, 60e3)
}

Solution

db.del('foo', { prewrite: false })

As well as:

db.put('foo', 'bar', { prewrite: false })
db.batch([], { prewrite: false })
db.batch().put('foo', 'bar', { prewrite: false })
db.batch().del('foo', { prewrite: false })
@vweevers vweevers added the enhancement New feature or request label Nov 20, 2022
@vweevers vweevers added this to the 2.0.0 milestone Nov 20, 2022
@vweevers
Copy link
Member Author

vweevers commented Nov 20, 2022

Only question is, if db is a sublevel, should it forward { prewrite: false } to its parent database? I think no, to keep it isolated.

@vweevers
Copy link
Member Author

vweevers commented Nov 20, 2022

The prewrite hook is fast, so technically this could also be solved in userland. Like so:

const bypass = Symbol('bypass')

db.hooks.prewrite.add(function (op, batch) {
  if (op[bypass]) return
})

await db.del('foo', { [bypass]: true })

And adding a prewrite option wouldn't be a breaking change, so I'm removing this from the v2 milestone. Not a blocker.

@vweevers vweevers removed this from the 2.0.0 milestone Nov 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

1 participant