do-counter-sharding
v1.2.1
Published
`npm i do-counter-sharding`
Downloads
1
Readme
DO COUNTER SHARDING
NPM
npm i do-counter-sharding
How to use
- Create you own class and extends from CounterDurableObject.
Do not export
CounterDurableObject
directly as a durable_object binding. - Set your preferences and export your class instead.
import { CounterDurableObject } from 'do-counter-sharding'
class Metrics extends CounterDurableObject {
static doNamespace = `METRICS_DO` // binding name of your wrangler.toml
static kvNamespace = `KV` // kv_namespace binding name in your wrangler.toml
static kvPrefix = `metrics` // prefix used when storing counters to KV - metrics~counters
static shardCount = 2 // number of shards that you want - can be change anytime - this should handle 200requests/s
static shardMinRequestToGlobal = 100 // higher number will write to global less often
static shardWriteToGlobalAfter = 1000 * 5 // 5s in ms - if the DO does not receive anymore increment after 5s it will write to the global counter
static globalMinWritesToKV = 100 // higher number will write to KV less often
static globalWriteToKVAfter = 1000 * 5// 5s in ms - if the DO does not receive anymore write from shards after 5s it will write to KV
}
export default {
fetch: (request, env) => {
const globalStub = Metrics.globalStub(env)
// globalStub.fetch()
const shardStub = Metrics.shardStub(env, Number(shardNumber))
// shardStub.fetch()
return new Response()
}
}
export { Metrics }
API
From Worker perspective
Check the test file ./test/index.ts how to implement in a worker
Global Worker
POST
/global/reset/:counterName
reset specific counter from globalGET
/global/counters
view global counters from global DurableObject storageGET
/global/writes
display write events from all shards (useful for understanding how it works)GET
/global/shardWrites
display write counts with sum totalGET
/global/shards
view shards current count
Shard Worker
GET
/shard/:shardNumber/counters
view current shard counters
POST
/shard/:shardNumber/write
write to global manually (useful if there was a bug and exceedMaxCount or afterNoIncrement
did not hit)
Worker
POST
/increment/:counterName
increment a global counter by dispatching work to other shardsPOST
/increments
increment global multiple counters from shards
GET
/counters
view global counters from KV
From Stub perspective
Global Stub
Using fetch /reset/:counterName
, /write
, /counters
, /writes
, /shardWrites
, /shards
// Metrics is a class extending CounterDurableObject
const globalStub = Metrics.globalStub(env)
globalStub.fetch(`/reset/{counterName}`, { method: `POST` })
you can also use method directly
const globalStub = Metrics.globalStub(env)
globalStub.reset(`{counterName}`)
Shard Stub
Using fetch /counters
, /write
, /increment/:counterName
, /increments
const shardStub = Metrics.shardStub(env)
shardStub.fetch(`/increment/{counterName}`, { method: `POST` } )
//you can also use method directly
shardStub.increment(`{counterName}`)
increment multiple counters in one request
const shardStub = Metrics.shardStub(env)
shardStub.fetch(`/increments`, { method: `POST`, body: JSON.stringify({ counter1: 1, counter2: 1 }) } )
//you can also use method directly
shardStub.increments({ counter1: 1, counter2: 1 })
Leaving shardNumber
empty will randomly choose a shard for you
DEV
npm run build
build files for publishing npm packagenpm run build-test
build test worker - used my miniflarenpm run test
run Worker DO with miniflarenpm run test-counter
run test scripts to send /increment post requests