@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.
- package/README.md +33 -44
- package/dist/index.min.js +1 -1
- package/dist/src/constants.d.ts +1 -4
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +1 -4
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +34 -63
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +138 -46
- package/dist/src/index.js.map +1 -1
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +107 -0
- package/dist/src/main.js.map +1 -0
- package/package.json +16 -11
- package/src/constants.ts +1 -4
- package/src/index.ts +160 -68
- package/src/main.ts +118 -0
- package/dist/src/perf-service.d.ts +0 -21
- package/dist/src/perf-service.d.ts.map +0 -1
- package/dist/src/perf-service.js +0 -169
- package/dist/src/perf-service.js.map +0 -1
- package/src/perf-service.ts +0 -207
package/dist/src/perf-service.js
DELETED
@@ -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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"}
|
package/src/perf-service.ts
DELETED
@@ -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
|
-
}
|