@libp2p/perf 1.1.15-78db573f9 → 1.1.15-8b82e68e8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,169 +0,0 @@
1
- import { logger } from '@libp2p/logger';
2
- import { pushable } from 'it-pushable';
3
- import { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_TRANSIENT_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js';
4
- const log = logger('libp2p:perf');
5
- export class PerfService {
6
- protocol;
7
- components;
8
- started;
9
- databuf;
10
- writeBlockSize;
11
- maxInboundStreams;
12
- maxOutboundStreams;
13
- runOnTransientConnection;
14
- constructor(components, init = {}) {
15
- this.components = components;
16
- this.started = false;
17
- this.protocol = init.protocolName ?? PROTOCOL_NAME;
18
- this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE;
19
- this.databuf = new ArrayBuffer(this.writeBlockSize);
20
- this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS;
21
- this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS;
22
- this.runOnTransientConnection = init.runOnTransientConnection ?? RUN_ON_TRANSIENT_CONNECTION;
23
- }
24
- async start() {
25
- await this.components.registrar.handle(this.protocol, (data) => {
26
- void this.handleMessage(data).catch((err) => {
27
- log.error('error handling perf protocol message', err);
28
- });
29
- }, {
30
- maxInboundStreams: this.maxInboundStreams,
31
- maxOutboundStreams: this.maxOutboundStreams,
32
- runOnTransientConnection: this.runOnTransientConnection
33
- });
34
- this.started = true;
35
- }
36
- async stop() {
37
- await this.components.registrar.unhandle(this.protocol);
38
- this.started = false;
39
- }
40
- isStarted() {
41
- return this.started;
42
- }
43
- async handleMessage(data) {
44
- const { stream } = data;
45
- try {
46
- const writeBlockSize = this.writeBlockSize;
47
- let bytesToSendBack;
48
- for await (const buf of stream.source) {
49
- if (bytesToSendBack == null) {
50
- // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty
51
- bytesToSendBack = Number(buf.getBigUint64(0, false));
52
- }
53
- // Ingest all the bufs and wait for the read side to close
54
- }
55
- if (bytesToSendBack == null) {
56
- throw new Error('bytesToSendBack was not set');
57
- }
58
- const uint8Buf = new Uint8Array(this.databuf);
59
- await stream.sink(async function* () {
60
- while (bytesToSendBack > 0) {
61
- let toSend = writeBlockSize;
62
- if (toSend > bytesToSendBack) {
63
- toSend = bytesToSendBack;
64
- }
65
- bytesToSendBack = bytesToSendBack - toSend;
66
- yield uint8Buf.subarray(0, toSend);
67
- }
68
- }());
69
- }
70
- catch (err) {
71
- stream.abort(err);
72
- }
73
- }
74
- async *measurePerformance(ma, sendBytes, receiveBytes, options = {}) {
75
- log('opening stream on protocol %s to %a', this.protocol, ma);
76
- const uint8Buf = new Uint8Array(this.databuf);
77
- const writeBlockSize = this.writeBlockSize;
78
- // start time should include connection establishment
79
- const initialStartTime = Date.now();
80
- const connection = await this.components.connectionManager.openConnection(ma, {
81
- ...options,
82
- force: options.reuseExistingConnection !== true
83
- });
84
- const stream = await connection.newStream(this.protocol, options);
85
- let lastAmountOfBytesSent = 0;
86
- let lastReportedTime = Date.now();
87
- let totalBytesSent = 0;
88
- // tell the remote how many bytes we will send. Up cast to 64 bit number
89
- // as if we send as ui32 we limit total transfer size to 4GB
90
- const view = new DataView(this.databuf);
91
- view.setBigUint64(0, BigInt(receiveBytes), false);
92
- log('sending %i bytes to %p', sendBytes, connection.remotePeer);
93
- try {
94
- const sendOutput = pushable({
95
- objectMode: true
96
- });
97
- void stream.sink(async function* () {
98
- // Send the number of bytes to receive
99
- yield uint8Buf.subarray(0, 8);
100
- while (sendBytes > 0) {
101
- options.signal?.throwIfAborted();
102
- let toSend = writeBlockSize;
103
- if (toSend > sendBytes) {
104
- toSend = sendBytes;
105
- }
106
- sendBytes = sendBytes - toSend;
107
- yield uint8Buf.subarray(0, toSend);
108
- if (Date.now() - lastReportedTime > 1000) {
109
- sendOutput.push({
110
- type: 'intermediary',
111
- timeSeconds: (Date.now() - lastReportedTime) / 1000,
112
- uploadBytes: lastAmountOfBytesSent,
113
- downloadBytes: 0
114
- });
115
- // record last reported time after `console.log` because it can
116
- // affect benchmark timings
117
- lastReportedTime = Date.now();
118
- lastAmountOfBytesSent = 0;
119
- }
120
- lastAmountOfBytesSent += toSend;
121
- totalBytesSent += toSend;
122
- }
123
- sendOutput.end();
124
- }())
125
- .catch(err => {
126
- sendOutput.end(err);
127
- });
128
- yield* sendOutput;
129
- // Read the received bytes
130
- let lastAmountOfBytesReceived = 0;
131
- lastReportedTime = Date.now();
132
- let totalBytesReceived = 0;
133
- for await (const buf of stream.source) {
134
- options.signal?.throwIfAborted();
135
- if (Date.now() - lastReportedTime > 1000) {
136
- yield {
137
- type: 'intermediary',
138
- timeSeconds: (Date.now() - lastReportedTime) / 1000,
139
- uploadBytes: 0,
140
- downloadBytes: lastAmountOfBytesReceived
141
- };
142
- // record last reported time after `console.log` because it can
143
- // affect benchmark timings
144
- lastReportedTime = Date.now();
145
- lastAmountOfBytesReceived = 0;
146
- }
147
- lastAmountOfBytesReceived += buf.byteLength;
148
- totalBytesReceived += buf.byteLength;
149
- }
150
- if (totalBytesReceived !== receiveBytes) {
151
- throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`);
152
- }
153
- yield {
154
- type: 'final',
155
- timeSeconds: (Date.now() - initialStartTime) / 1000,
156
- uploadBytes: totalBytesSent,
157
- downloadBytes: totalBytesReceived
158
- };
159
- log('performed %s to %p', this.protocol, connection.remotePeer);
160
- await stream.close();
161
- }
162
- catch (err) {
163
- log('error sending %s bytes to %p: %s', totalBytesSent, connection.remotePeer, err);
164
- stream.abort(err);
165
- throw err;
166
- }
167
- }
168
- }
169
- //# sourceMappingURL=perf-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"perf-service.js","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"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"}
@@ -1,207 +0,0 @@
1
- import { logger } from '@libp2p/logger'
2
- import { pushable } from 'it-pushable'
3
- import { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_TRANSIENT_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'
4
- import type { PerfOptions, PerfOutput, PerfServiceComponents, PerfServiceInit, PerfService as PerfServiceInterface } from './index.js'
5
- import type { Startable } from '@libp2p/interface/startable'
6
- import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
7
- import type { Multiaddr } from '@multiformats/multiaddr'
8
-
9
- const log = logger('libp2p:perf')
10
-
11
- export class PerfService implements Startable, PerfServiceInterface {
12
- public readonly protocol: string
13
- private readonly components: PerfServiceComponents
14
- private started: boolean
15
- private readonly databuf: ArrayBuffer
16
- private readonly writeBlockSize: number
17
- private readonly maxInboundStreams: number
18
- private readonly maxOutboundStreams: number
19
- private readonly runOnTransientConnection: boolean
20
-
21
- constructor (components: PerfServiceComponents, init: PerfServiceInit = {}) {
22
- this.components = components
23
- this.started = false
24
- this.protocol = init.protocolName ?? PROTOCOL_NAME
25
- this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE
26
- this.databuf = new ArrayBuffer(this.writeBlockSize)
27
- this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS
28
- this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS
29
- this.runOnTransientConnection = init.runOnTransientConnection ?? RUN_ON_TRANSIENT_CONNECTION
30
- }
31
-
32
- async start (): Promise<void> {
33
- await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {
34
- void this.handleMessage(data).catch((err) => {
35
- log.error('error handling perf protocol message', err)
36
- })
37
- }, {
38
- maxInboundStreams: this.maxInboundStreams,
39
- maxOutboundStreams: this.maxOutboundStreams,
40
- runOnTransientConnection: this.runOnTransientConnection
41
- })
42
- this.started = true
43
- }
44
-
45
- async stop (): Promise<void> {
46
- await this.components.registrar.unhandle(this.protocol)
47
- this.started = false
48
- }
49
-
50
- isStarted (): boolean {
51
- return this.started
52
- }
53
-
54
- async handleMessage (data: IncomingStreamData): Promise<void> {
55
- const { stream } = data
56
-
57
- try {
58
- const writeBlockSize = this.writeBlockSize
59
-
60
- let bytesToSendBack: number | undefined
61
-
62
- for await (const buf of stream.source) {
63
- if (bytesToSendBack == null) {
64
- // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty
65
- bytesToSendBack = Number(buf.getBigUint64(0, false))
66
- }
67
- // Ingest all the bufs and wait for the read side to close
68
- }
69
-
70
- if (bytesToSendBack == null) {
71
- throw new Error('bytesToSendBack was not set')
72
- }
73
-
74
- const uint8Buf = new Uint8Array(this.databuf)
75
-
76
- await stream.sink(async function * () {
77
- while (bytesToSendBack > 0) {
78
- let toSend: number = writeBlockSize
79
- if (toSend > bytesToSendBack) {
80
- toSend = bytesToSendBack
81
- }
82
-
83
- bytesToSendBack = bytesToSendBack - toSend
84
- yield uint8Buf.subarray(0, toSend)
85
- }
86
- }())
87
- } catch (err: any) {
88
- stream.abort(err)
89
- }
90
- }
91
-
92
- async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {
93
- log('opening stream on protocol %s to %a', this.protocol, ma)
94
-
95
- const uint8Buf = new Uint8Array(this.databuf)
96
- const writeBlockSize = this.writeBlockSize
97
-
98
- // start time should include connection establishment
99
- const initialStartTime = Date.now()
100
- const connection = await this.components.connectionManager.openConnection(ma, {
101
- ...options,
102
- force: options.reuseExistingConnection !== true
103
- })
104
- const stream = await connection.newStream(this.protocol, options)
105
-
106
- let lastAmountOfBytesSent = 0
107
- let lastReportedTime = Date.now()
108
- let totalBytesSent = 0
109
-
110
- // tell the remote how many bytes we will send. Up cast to 64 bit number
111
- // as if we send as ui32 we limit total transfer size to 4GB
112
- const view = new DataView(this.databuf)
113
- view.setBigUint64(0, BigInt(receiveBytes), false)
114
-
115
- log('sending %i bytes to %p', sendBytes, connection.remotePeer)
116
-
117
- try {
118
- const sendOutput = pushable<PerfOutput>({
119
- objectMode: true
120
- })
121
-
122
- void stream.sink(async function * () {
123
- // Send the number of bytes to receive
124
- yield uint8Buf.subarray(0, 8)
125
-
126
- while (sendBytes > 0) {
127
- options.signal?.throwIfAborted()
128
-
129
- let toSend: number = writeBlockSize
130
- if (toSend > sendBytes) {
131
- toSend = sendBytes
132
- }
133
- sendBytes = sendBytes - toSend
134
- yield uint8Buf.subarray(0, toSend)
135
-
136
- if (Date.now() - lastReportedTime > 1000) {
137
- sendOutput.push({
138
- type: 'intermediary',
139
- timeSeconds: (Date.now() - lastReportedTime) / 1000,
140
- uploadBytes: lastAmountOfBytesSent,
141
- downloadBytes: 0
142
- })
143
-
144
- // record last reported time after `console.log` because it can
145
- // affect benchmark timings
146
- lastReportedTime = Date.now()
147
- lastAmountOfBytesSent = 0
148
- }
149
-
150
- lastAmountOfBytesSent += toSend
151
- totalBytesSent += toSend
152
- }
153
-
154
- sendOutput.end()
155
- }())
156
- .catch(err => {
157
- sendOutput.end(err)
158
- })
159
-
160
- yield * sendOutput
161
-
162
- // Read the received bytes
163
- let lastAmountOfBytesReceived = 0
164
- lastReportedTime = Date.now()
165
- let totalBytesReceived = 0
166
-
167
- for await (const buf of stream.source) {
168
- options.signal?.throwIfAborted()
169
-
170
- if (Date.now() - lastReportedTime > 1000) {
171
- yield {
172
- type: 'intermediary',
173
- timeSeconds: (Date.now() - lastReportedTime) / 1000,
174
- uploadBytes: 0,
175
- downloadBytes: lastAmountOfBytesReceived
176
- }
177
-
178
- // record last reported time after `console.log` because it can
179
- // affect benchmark timings
180
- lastReportedTime = Date.now()
181
- lastAmountOfBytesReceived = 0
182
- }
183
-
184
- lastAmountOfBytesReceived += buf.byteLength
185
- totalBytesReceived += buf.byteLength
186
- }
187
-
188
- if (totalBytesReceived !== receiveBytes) {
189
- throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)
190
- }
191
-
192
- yield {
193
- type: 'final',
194
- timeSeconds: (Date.now() - initialStartTime) / 1000,
195
- uploadBytes: totalBytesSent,
196
- downloadBytes: totalBytesReceived
197
- }
198
-
199
- log('performed %s to %p', this.protocol, connection.remotePeer)
200
- await stream.close()
201
- } catch (err: any) {
202
- log('error sending %s bytes to %p: %s', totalBytesSent, connection.remotePeer, err)
203
- stream.abort(err)
204
- throw err
205
- }
206
- }
207
- }