Skip to content

Commit 581574d

Browse files
authored
feat: add tracked list to utils (#2338)
To allow tracking sizes of internal lists using libp2p metrics, add a tracked list type similar to tracked map.
1 parent 388d02b commit 581574d

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

packages/utils/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@
8484
"types": "./dist/src/stream-to-ma-conn.d.ts",
8585
"import": "./dist/src/stream-to-ma-conn.js"
8686
},
87+
"./tracked-list": {
88+
"types": "./dist/src/tracked-list.d.ts",
89+
"import": "./dist/src/tracked-list.js"
90+
},
8791
"./tracked-map": {
8892
"types": "./dist/src/tracked-map.d.ts",
8993
"import": "./dist/src/tracked-map.js"

packages/utils/src/tracked-list.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { Metrics } from '@libp2p/interface'
2+
3+
export interface CreateTrackedListInit {
4+
/**
5+
* The metric name to use
6+
*/
7+
name: string
8+
9+
/**
10+
* A metrics implementation
11+
*/
12+
metrics?: Metrics
13+
}
14+
15+
export function trackedList <V> (config: CreateTrackedListInit): V[] {
16+
const { name, metrics } = config
17+
const list: V[] = []
18+
19+
metrics?.registerMetric(name, {
20+
calculate: () => {
21+
return list.length
22+
}
23+
})
24+
25+
return list
26+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { expect } from 'aegir/chai'
2+
import { stubInterface } from 'sinon-ts'
3+
import { trackedList } from '../src/tracked-list.js'
4+
import type { Metric, Metrics } from '@libp2p/interface'
5+
import type { SinonStubbedInstance } from 'sinon'
6+
7+
describe('tracked-list', () => {
8+
let metrics: SinonStubbedInstance<Metrics>
9+
10+
beforeEach(() => {
11+
metrics = stubInterface<Metrics>()
12+
})
13+
14+
it('should return a list with metrics', () => {
15+
const name = 'system_component_metric'
16+
const metric = stubInterface<Metric>()
17+
// @ts-expect-error the wrong overload is selected
18+
metrics.registerMetric.withArgs(name).returns(metric)
19+
20+
const list = trackedList({
21+
name,
22+
metrics
23+
})
24+
25+
expect(list).to.be.an.instanceOf(Array)
26+
expect(metrics.registerMetric.calledWith(name)).to.be.true()
27+
})
28+
29+
it('should return a map without metrics', () => {
30+
const name = 'system_component_metric'
31+
const metric = stubInterface<Metric>()
32+
// @ts-expect-error the wrong overload is selected
33+
metrics.registerMetric.withArgs(name).returns(metric)
34+
35+
const list = trackedList({
36+
name
37+
})
38+
39+
expect(list).to.be.an.instanceOf(Array)
40+
expect(metrics.registerMetric.called).to.be.false()
41+
})
42+
43+
it('should track metrics', () => {
44+
const name = 'system_component_metric'
45+
46+
const list = trackedList({
47+
name,
48+
metrics
49+
})
50+
51+
const calculate = metrics.registerMetric.getCall(0).args[1].calculate
52+
53+
expect(list).to.be.an.instanceOf(Array)
54+
expect(calculate()).to.equal(0)
55+
56+
list.push('value1')
57+
58+
expect(calculate()).to.equal(1)
59+
60+
list.push('value2')
61+
62+
expect(calculate()).to.equal(2)
63+
64+
list.push('value3')
65+
66+
expect(calculate()).to.equal(3)
67+
68+
list.pop()
69+
70+
expect(calculate()).to.equal(2)
71+
72+
list.splice(0, list.length)
73+
74+
expect(calculate()).to.equal(0)
75+
})
76+
})

packages/utils/typedoc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"./src/multiaddr/is-loopback.ts",
1111
"./src/multiaddr/is-private.ts",
1212
"./src/peer-job-queue.ts",
13-
"./src/stream-to-ma-conn.ts"
13+
"./src/stream-to-ma-conn.ts",
14+
"./src/tracked-list.ts",
15+
"./src/tracked-map.ts",
1416
]
1517
}

0 commit comments

Comments
 (0)