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

feat: use storage and invalidation #7

Merged
merged 22 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
name: ci

on: [push, pull_request]

on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]

redis-tag: [5, 6]
services:
redis:
image: redis:${{ matrix.redis-tag }}
ports:
- 6379:6379
options: --entrypoint redis-server
steps:
- uses: actions/checkout@v2

Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*

package-lock.json

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

Expand Down Expand Up @@ -102,3 +104,6 @@ dist

# TernJS port file
.tern-port

.vscode
docker-compose.yml
29 changes: 29 additions & 0 deletions bench/bench.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

CWD="$(dirname $0)"

TTL=1
ENTRIES=10000
REFERENCES=0
GET=1
INVALIDATE=0


echo "Running benchmarks..."

node $CWD/storage.js memory $TTL $ENTRIES $REFERENCES $GET $INVALIDATE

echo -e "\n-----\n"

node $CWD/storage.js redis $TTL $ENTRIES $REFERENCES $GET $INVALIDATE

echo -e "\n-----\n"

REFERENCES=1
INVALIDATE=1

node $CWD/storage.js memory $TTL $ENTRIES $REFERENCES $GET $INVALIDATE

echo -e "\n-----\n"

node $CWD/storage.js redis $TTL $ENTRIES $REFERENCES $GET $INVALIDATE
73 changes: 73 additions & 0 deletions bench/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use strict'

const { hrtime } = require('process')
const path = require('path')
const Redis = require('ioredis')
const createStorage = require(path.resolve(__dirname, '../storage'))

// NOTE: this is a very basic benchmarks for tweaking
// performance is effected by keys and references size

function ms (ns) {
return Number(ns) / 1e6
}

async function main () {
let [,, type, ttl, entries, references, set, invalidate] = process.argv

ttl = Number(ttl)
references = references === 'true' || references === '1'
set = set === 'true' || set === '1'
invalidate = invalidate === 'true' || invalidate === '1'

console.log(`
type: ${type}
ttl: ${ttl}
entries: ${entries}
references: ${references}
set: ${set}
invalidate: ${invalidate}
`)

const options = {
invalidation: invalidate
}

if (type === 'redis') {
options.client = new Redis({ enableAutoPipelining: true })
}

let start = hrtime.bigint()
const storage = await createStorage(type, options)
let end = hrtime.bigint()
console.log(`storage created in ${ms(end - start)} ms`)

start = hrtime.bigint()
for (let i = 0; i < entries; i++) {
await storage.set(`key-${i}`, `value-${i}`, ttl, references ? [`reference-key-${i}`] : null)
}
end = hrtime.bigint()
console.log(`set ${entries} entries (ttl: ${!!ttl}, references: ${!!references}) in ${ms(end - start)} ms`)

if (set) {
start = hrtime.bigint()
for (let i = 0; i < entries; i++) {
await storage.get(`key-${i}`)
}
end = hrtime.bigint()
console.log(`get ${entries} entries (ttl: ${!!ttl}, references: ${!!references}) in ${ms(end - start)} ms`)
}

if (invalidate) {
start = hrtime.bigint()
for (let i = 0; i < entries; i++) {
await storage.invalidate([`reference-key-${i}`])
}
end = hrtime.bigint()
console.log(`invalidate ${entries} entries (ttl: ${!!ttl}, references: ${!!references}) in ${ms(end - start)} ms`)
}

options.client && options.client.disconnect()
}

main()
11 changes: 10 additions & 1 deletion example.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { Cache } from './index.js'

// TODO

const cache = new Cache({
ttl: 5 // seconds
ttl: 5, // default ttl, in seconds
storage: new MemoryStorage({
size: 2048,
log: pino() // ...
}), // or new RedisStorage or AsyncLocalStorageWrapper
onDedupe: (key) => {
console.log('deduped', key)
}
})

cache.define('fetchSomething', async (k) => {
Expand Down
47 changes: 47 additions & 0 deletions examples/redis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict'

const createStorage = require('../storage')
const { Cache } = require('../')
const Redis = require('ioredis')

// TODO

async function main () {
const redisClient = new Redis()
const redisListener = new Redis()

const cache = new Cache({
ttl: 2, // default ttl, in seconds
storage: await createStorage('redis', { client: redisClient, log: console }),
// TODO listener:redisListener / autoPipelining:true
listener: redisListener,
simone-sanfratello marked this conversation as resolved.
Show resolved Hide resolved
onDedupe: (key) => {
console.log('deduped', key)
}
})

cache.define('fetchSomething', {
references: (args, key, result) => ['somethings', `some-${result}`]
}, async (k) => {
console.log('query', k)
// query 42
// query 24

return { k }
})

const p1 = cache.fetchSomething(42)
const p2 = cache.fetchSomething(24)
const p3 = cache.fetchSomething(42)

const res = await Promise.all([p1, p2, p3])

console.log(res)
}
// [
// { k: 42 },
// { k: 24 }
// { k: 42 }
// ]

main()
Loading