Skip to content

Commit

Permalink
docs: clarify about atomic operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed May 30, 2024
1 parent 3792580 commit c1c4d4f
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 4 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ Originally this library was implemented using [hashes](https://redis.io/docs/dat

Since we need to do that all the time, we prefer to use key/value. Also this approach allow to customize serializer/deserializer, which is JSON by default.

## Are writting operations atomic?

No, writes operatoins are not atomic because there are very few use cases where that matters. **openkey** is designed to process a constant stream of requests, where the only thing important to control reaching the limit of each plan.

In case you need it, you can combine **openkey** with [superlock](https://github.com/Kikobeats/superlock), check the following [example](https://github.com/microlinkhq/openkey/blob/9df977877e5066478020332bffb0c1677a5cd89e/test/usage.js#L115-L138).

# License

**openkey** © [microlink.io](https://microlink.io), released under the [MIT](https://github.com/microlinkhq/openkey/blob/master/LICENSE.md) License.<br>
Expand Down
Binary file added dump.rdb
Binary file not shown.
4 changes: 4 additions & 0 deletions examples/server/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"scripts": {
"dev": "watchexec --on-busy-update=restart --exts js,yml --clear=clear 'node index.js'"
},
"dependencies": {
"http-body": "latest",
"send-http": "latest"
}
}
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@
},
"keywords": [],
"dependencies": {
"http-body": "~1.0.11",
"json-buffer": "~3.0.1",
"mri": "~1.2.0",
"ms": "~2.1.3",
"send-http": "~1.0.6"
"ms": "~2.1.3"
},
"devDependencies": {
"@commitlint/cli": "latest",
Expand Down Expand Up @@ -62,7 +61,8 @@
"postcss-focus": "latest",
"simple-git-hooks": "latest",
"standard": "latest",
"standard-version": "latest"
"standard-version": "latest",
"superlock": "latet"
},
"engines": {
"node": ">= 18"
Expand Down
26 changes: 26 additions & 0 deletions test/usage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const { setTimeout } = require('timers/promises')
const { withLock } = require('superlock')
const { randomUUID } = require('crypto')
const Redis = require('ioredis')
const test = require('ava')
Expand Down Expand Up @@ -110,3 +111,28 @@ test(".increment # don't increment more than the limit", async t => {
t.is(usage.remaining, 0)
}
})

test('.increment # handle race conditions (using superlock)', async t => {
const lock = withLock()

const plan = await openkey.plans.create({
id: randomUUID(),
limit: 1000,
period: '100ms'
})
const key = await openkey.keys.create({ plan: plan.id })

await Promise.all(
[...Array(100).keys()].map(() =>
lock(async () => {
const { pending, ...usage } = await openkey.usage.increment(key.value)
await pending
return usage
})
)
)

const usage = await openkey.usage(key.value)
t.is(usage.limit, 1000)
t.is(usage.remaining, 900)
})

0 comments on commit c1c4d4f

Please sign in to comment.