Skip to content

Commit

Permalink
feat: add tracked list to utils (#2338)
Browse files Browse the repository at this point in the history
To allow tracking sizes of internal lists using libp2p metrics, add
a tracked list type similar to tracked map.
  • Loading branch information
achingbrain authored Jan 6, 2024
1 parent 388d02b commit 581574d
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@
"types": "./dist/src/stream-to-ma-conn.d.ts",
"import": "./dist/src/stream-to-ma-conn.js"
},
"./tracked-list": {
"types": "./dist/src/tracked-list.d.ts",
"import": "./dist/src/tracked-list.js"
},
"./tracked-map": {
"types": "./dist/src/tracked-map.d.ts",
"import": "./dist/src/tracked-map.js"
Expand Down
26 changes: 26 additions & 0 deletions packages/utils/src/tracked-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Metrics } from '@libp2p/interface'

export interface CreateTrackedListInit {
/**
* The metric name to use
*/
name: string

/**
* A metrics implementation
*/
metrics?: Metrics
}

export function trackedList <V> (config: CreateTrackedListInit): V[] {
const { name, metrics } = config
const list: V[] = []

metrics?.registerMetric(name, {
calculate: () => {
return list.length
}
})

return list
}
76 changes: 76 additions & 0 deletions packages/utils/test/tracked-list.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { expect } from 'aegir/chai'
import { stubInterface } from 'sinon-ts'
import { trackedList } from '../src/tracked-list.js'
import type { Metric, Metrics } from '@libp2p/interface'
import type { SinonStubbedInstance } from 'sinon'

describe('tracked-list', () => {
let metrics: SinonStubbedInstance<Metrics>

beforeEach(() => {
metrics = stubInterface<Metrics>()
})

it('should return a list with metrics', () => {
const name = 'system_component_metric'
const metric = stubInterface<Metric>()
// @ts-expect-error the wrong overload is selected
metrics.registerMetric.withArgs(name).returns(metric)

const list = trackedList({
name,
metrics
})

expect(list).to.be.an.instanceOf(Array)
expect(metrics.registerMetric.calledWith(name)).to.be.true()
})

it('should return a map without metrics', () => {
const name = 'system_component_metric'
const metric = stubInterface<Metric>()
// @ts-expect-error the wrong overload is selected
metrics.registerMetric.withArgs(name).returns(metric)

const list = trackedList({
name
})

expect(list).to.be.an.instanceOf(Array)
expect(metrics.registerMetric.called).to.be.false()
})

it('should track metrics', () => {
const name = 'system_component_metric'

const list = trackedList({
name,
metrics
})

const calculate = metrics.registerMetric.getCall(0).args[1].calculate

expect(list).to.be.an.instanceOf(Array)
expect(calculate()).to.equal(0)

list.push('value1')

expect(calculate()).to.equal(1)

list.push('value2')

expect(calculate()).to.equal(2)

list.push('value3')

expect(calculate()).to.equal(3)

list.pop()

expect(calculate()).to.equal(2)

list.splice(0, list.length)

expect(calculate()).to.equal(0)
})
})
4 changes: 3 additions & 1 deletion packages/utils/typedoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"./src/multiaddr/is-loopback.ts",
"./src/multiaddr/is-private.ts",
"./src/peer-job-queue.ts",
"./src/stream-to-ma-conn.ts"
"./src/stream-to-ma-conn.ts",
"./src/tracked-list.ts",
"./src/tracked-map.ts",
]
}

0 comments on commit 581574d

Please sign in to comment.