@libp2p/perf 4.0.45 → 4.0.46-79473c99a
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/dist/index.min.js +1 -1
- package/dist/index.min.js.map +3 -3
- package/dist/src/perf-service.js +9 -9
- package/dist/src/perf-service.js.map +1 -1
- package/package.json +5 -5
- package/src/perf-service.ts +10 -10
- package/dist/typedoc-urls.json +0 -14
package/dist/index.min.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
(function (root, factory) {(typeof module === 'object' && module.exports) ? module.exports = factory() : root.Libp2PPerf = factory()}(typeof self !== 'undefined' ? self : this, function () {
|
2
|
-
"use strict";var Libp2PPerf=(()=>{var
|
2
|
+
"use strict";var Libp2PPerf=(()=>{var D=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var k=(i,t)=>{for(var e in t)D(i,e,{get:t[e],enumerable:!0})},A=(i,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of M(t))!v.call(i,r)&&r!==e&&D(i,r,{get:()=>t[r],enumerable:!(o=T(t,r))||o.enumerable});return i};var z=i=>A(D({},"__esModule",{value:!0}),i);var K={};k(K,{perf:()=>j});function g(){let i={};return i.promise=new Promise((t,e)=>{i.resolve=t,i.reject=e}),i}var E=class{buffer;mask;top;btm;next;constructor(t){if(!(t>0)||(t-1&t)!==0)throw new Error("Max size for a FixedFIFO should be a power of two");this.buffer=new Array(t),this.mask=t-1,this.top=0,this.btm=0,this.next=null}push(t){return this.buffer[this.top]!==void 0?!1:(this.buffer[this.top]=t,this.top=this.top+1&this.mask,!0)}shift(){let t=this.buffer[this.btm];if(t!==void 0)return this.buffer[this.btm]=void 0,this.btm=this.btm+1&this.mask,t}isEmpty(){return this.buffer[this.btm]===void 0}},y=class{size;hwm;head;tail;constructor(t={}){this.hwm=t.splitLimit??16,this.head=new E(this.hwm),this.tail=this.head,this.size=0}calculateSize(t){return t?.byteLength!=null?t.byteLength:1}push(t){if(t?.value!=null&&(this.size+=this.calculateSize(t.value)),!this.head.push(t)){let e=this.head;this.head=e.next=new E(2*this.head.buffer.length),this.head.push(t)}}shift(){let t=this.tail.shift();if(t===void 0&&this.tail.next!=null){let e=this.tail.next;this.tail.next=null,this.tail=e,t=this.tail.shift()}return t?.value!=null&&(this.size-=this.calculateSize(t.value)),t}isEmpty(){return this.head.isEmpty()}};var N=class extends Error{type;code;constructor(t,e){super(t??"The operation was aborted"),this.type="aborted",this.code=e??"ABORT_ERR"}};function _(i={}){return C(e=>{let o=e.shift();if(o==null)return{done:!0};if(o.error!=null)throw o.error;return{done:o.done===!0,value:o.value}},i)}function C(i,t){t=t??{};let e=t.onEnd,o=new y,r,l,s,S=g(),a=async()=>{try{return o.isEmpty()?s?{done:!0}:await new Promise((n,h)=>{l=d=>{l=null,o.push(d);try{n(i(o))}catch(p){h(p)}return r}}):i(o)}finally{o.isEmpty()&&queueMicrotask(()=>{S.resolve(),S=g()})}},f=n=>l!=null?l(n):(o.push(n),r),c=n=>(o=new y,l!=null?l({error:n}):(o.push({error:n}),r)),m=n=>{if(s)return r;if(t?.objectMode!==!0&&n?.byteLength==null)throw new Error("objectMode was not true but tried to push non-Uint8Array value");return f({done:!1,value:n})},w=n=>s?r:(s=!0,n!=null?c(n):f({done:!0})),x=()=>(o=new y,w(),{done:!0}),B=n=>(w(n),{done:!0});if(r={[Symbol.asyncIterator](){return this},next:a,return:x,throw:B,push:m,end:w,get readableLength(){return o.size},onEmpty:async n=>{let h=n?.signal;if(h?.throwIfAborted(),o.isEmpty())return;let d,p;h!=null&&(d=new Promise((u,I)=>{p=()=>{I(new N)},h.addEventListener("abort",p)}));try{await Promise.race([S.promise,d])}finally{p!=null&&h!=null&&h?.removeEventListener("abort",p)}}},e==null)return r;let b=r;return r={[Symbol.asyncIterator](){return this},next(){return b.next()},throw(n){return b.throw(n),e!=null&&(e(n),e=void 0),{done:!0}},return(){return b.return(),e!=null&&(e(),e=void 0),{done:!0}},push:m,end(n){return b.end(n),e!=null&&(e(n),e=void 0),r},get readableLength(){return b.readableLength},onEmpty:n=>b.onEmpty(n)},r}var L="/perf/1.0.0";var O=class{log;protocol;components;started;buf;writeBlockSize;maxInboundStreams;maxOutboundStreams;runOnLimitedConnection;constructor(t,e={}){this.components=t,this.log=t.logger.forComponent("libp2p:perf"),this.started=!1,this.protocol=e.protocolName??L,this.writeBlockSize=e.writeBlockSize??65536,this.buf=new ArrayBuffer(this.writeBlockSize),this.maxInboundStreams=e.maxInboundStreams??1,this.maxOutboundStreams=e.maxOutboundStreams??1,this.runOnLimitedConnection=e.runOnLimitedConnection??!1}[Symbol.toStringTag]="@libp2p/perf";async start(){await this.components.registrar.handle(this.protocol,t=>{this.handleMessage(t).catch(e=>{this.log.error("error handling perf protocol message - %e",e)})},{maxInboundStreams:this.maxInboundStreams,maxOutboundStreams:this.maxOutboundStreams,runOnLimitedConnection:this.runOnLimitedConnection}),this.started=!0}async stop(){await this.components.registrar.unhandle(this.protocol),this.started=!1}isStarted(){return this.started}async handleMessage(t){let{stream:e}=t;try{let o=this.writeBlockSize,r;for await(let s of e.source)r==null&&(r=Number(s.getBigUint64(0,!1)));if(r==null)throw new Error("bytesToSendBack was not set");let l=new Uint8Array(this.buf,0,this.buf.byteLength);await e.sink(async function*(){for(;r>0;){let s=o;s>r&&(s=r),r=r-s,yield l.subarray(0,s)}}())}catch(o){e.abort(o)}}async*measurePerformance(t,e,o,r={}){let l=new Uint8Array(this.buf),s=this.writeBlockSize,S=Date.now(),a=Date.now(),f=await this.components.connectionManager.openConnection(t,{...r,force:r.reuseExistingConnection!==!0}),c=f.log.newScope("perf");c("opened connection after %d ms",Date.now()-a),a=Date.now();let m=await f.newStream(this.protocol,r);c("opened stream after %d ms",Date.now()-a),a=Date.now();let w=0,x=0,B=Date.now();new DataView(this.buf).setBigUint64(0,BigInt(o),!1),c("sending %i bytes to %p",e,f.remotePeer);try{let n=_({objectMode:!0});m.sink(async function*(){for(yield l.subarray(0,8);e>0;){let u=s;u>e&&(u=e),yield l.subarray(0,u),e-=u,Date.now()-a>1e3&&(n.push({type:"intermediary",timeSeconds:(Date.now()-a)/1e3,uploadBytes:w,downloadBytes:0}),a=Date.now(),w=0),w+=u,x+=u}n.end()}()).catch(u=>{n.end(u)}),yield*n,c("upload complete after %d ms",Date.now()-B);let h=0;a=Date.now();let d=0,p=Date.now();for await(let u of m.source)Date.now()-a>1e3&&(yield{type:"intermediary",timeSeconds:(Date.now()-a)/1e3,uploadBytes:0,downloadBytes:h},a=Date.now(),h=0),h+=u.byteLength,d+=u.byteLength;if(c("download complete after %d ms",Date.now()-p),d!==o)throw new Error(`Expected to receive ${o} bytes, but received ${d}`);yield{type:"final",timeSeconds:(Date.now()-S)/1e3,uploadBytes:x,downloadBytes:d},c("performed %s to %p",this.protocol,f.remotePeer),await m.close()}catch(n){throw c("error sending %d/%d bytes to %p: %s",x,e,f.remotePeer,n),m.abort(n),n}}};function j(i={}){return t=>new O(t,i)}return z(K);})();
|
3
3
|
return Libp2PPerf}));
|
4
4
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.min.js.map
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"version": 3,
|
3
3
|
"sources": ["../src/index.ts", "../../../node_modules/p-defer/index.js", "../../../node_modules/it-pushable/src/fifo.ts", "../../../node_modules/it-pushable/src/index.ts", "../src/constants.ts", "../src/perf-service.ts"],
|
4
|
-
"sourcesContent": ["/**\n * @packageDocumentation\n *\n * The {@link Perf} service implements the [perf protocol](https://github.com/libp2p/specs/blob/master/perf/perf.md), which can be used to measure transfer performance within and across libp2p implementations.\n *\n * @example\n *\n * ```typescript\n * import { noise } from '@chainsafe/libp2p-noise'\n * import { yamux } from '@chainsafe/libp2p-yamux'\n * import { tcp } from '@libp2p/tcp'\n * import { createLibp2p, type Libp2p } from 'libp2p'\n * import { plaintext } from '@libp2p/plaintext'\n * import { perf, type Perf } from '@libp2p/perf'\n *\n * const ONE_MEG = 1024 * 1024\n * const UPLOAD_BYTES = ONE_MEG * 1024\n * const DOWNLOAD_BYTES = ONE_MEG * 1024\n *\n * async function createNode (): Promise<Libp2p<{ perf: Perf }>> {\n * return createLibp2p({\n * addresses: {\n * listen: [\n * '/ip4/0.0.0.0/tcp/0'\n * ]\n * },\n * transports: [\n * tcp()\n * ],\n * connectionEncrypters: [\n * noise(), plaintext()\n * ],\n * streamMuxers: [\n * yamux()\n * ],\n * services: {\n * perf: perf()\n * }\n * })\n * }\n *\n * const libp2p1 = await createNode()\n * const libp2p2 = await createNode()\n *\n * for await (const output of libp2p1.services.perf.measurePerformance(libp2p2.getMultiaddrs()[0], UPLOAD_BYTES, DOWNLOAD_BYTES)) {\n * console.info(output)\n * }\n *\n * await libp2p1.stop()\n * await libp2p2.stop()\n * ```\n */\n\nimport { Perf as PerfClass } from './perf-service.js'\nimport type { AbortOptions, ComponentLogger } from '@libp2p/interface'\nimport type { ConnectionManager, Registrar } from '@libp2p/interface-internal'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport interface PerfOptions extends AbortOptions {\n /**\n * By default measuring perf should include the time it takes to establish a\n * connection, so a new connection will be opened for every performance run.\n *\n * To override this and re-use an existing connection if one is present, pass\n * `true` here.\n *\n * @default false\n */\n reuseExistingConnection?: boolean\n}\n\nexport interface Perf {\n measurePerformance(multiaddr: Multiaddr, sendBytes: number, recvBytes: number, options?: PerfOptions): AsyncGenerator<PerfOutput>\n}\n\nexport interface PerfOutput {\n type: 'connection' | 'stream' | 'intermediary' | 'final'\n timeSeconds: number\n uploadBytes: number\n downloadBytes: number\n}\n\nexport interface PerfInit {\n protocolName?: string\n maxInboundStreams?: number\n maxOutboundStreams?: number\n runOnLimitedConnection?: boolean\n\n /**\n * Data sent/received will be sent in chunks of this size\n *\n * @default 65536\n */\n writeBlockSize?: number\n}\n\nexport interface PerfComponents {\n registrar: Registrar\n connectionManager: ConnectionManager\n logger: ComponentLogger\n}\n\nexport function perf (init: PerfInit = {}): (components: PerfComponents) => Perf {\n return (components) => new PerfClass(components, init)\n}\n", "export default function pDefer() {\n\tconst deferred = {};\n\n\tdeferred.promise = new Promise((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\n\treturn deferred;\n}\n", "// ported from https://www.npmjs.com/package/fast-fifo\n\nexport interface Next<T> {\n done?: boolean\n error?: Error\n value?: T\n}\n\nclass FixedFIFO<T> {\n public buffer: Array<Next<T> | undefined>\n private readonly mask: number\n private top: number\n private btm: number\n public next: FixedFIFO<T> | null\n\n constructor (hwm: number) {\n if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) {\n throw new Error('Max size for a FixedFIFO should be a power of two')\n }\n\n this.buffer = new Array(hwm)\n this.mask = hwm - 1\n this.top = 0\n this.btm = 0\n this.next = null\n }\n\n push (data: Next<T>): boolean {\n if (this.buffer[this.top] !== undefined) {\n return false\n }\n\n this.buffer[this.top] = data\n this.top = (this.top + 1) & this.mask\n\n return true\n }\n\n shift (): Next<T> | undefined {\n const last = this.buffer[this.btm]\n\n if (last === undefined) {\n return undefined\n }\n\n this.buffer[this.btm] = undefined\n this.btm = (this.btm + 1) & this.mask\n return last\n }\n\n isEmpty (): boolean {\n return this.buffer[this.btm] === undefined\n }\n}\n\nexport interface FIFOOptions {\n /**\n * When the queue reaches this size, it will be split into head/tail parts\n */\n splitLimit?: number\n}\n\nexport class FIFO<T> {\n public size: number\n private readonly hwm: number\n private head: FixedFIFO<T>\n private tail: FixedFIFO<T>\n\n constructor (options: FIFOOptions = {}) {\n this.hwm = options.splitLimit ?? 16\n this.head = new FixedFIFO<T>(this.hwm)\n this.tail = this.head\n this.size = 0\n }\n\n calculateSize (obj: any): number {\n if (obj?.byteLength != null) {\n return obj.byteLength\n }\n\n return 1\n }\n\n push (val: Next<T>): void {\n if (val?.value != null) {\n this.size += this.calculateSize(val.value)\n }\n\n if (!this.head.push(val)) {\n const prev = this.head\n this.head = prev.next = new FixedFIFO<T>(2 * this.head.buffer.length)\n this.head.push(val)\n }\n }\n\n shift (): Next<T> | undefined {\n let val = this.tail.shift()\n\n if (val === undefined && (this.tail.next != null)) {\n const next = this.tail.next\n this.tail.next = null\n this.tail = next\n val = this.tail.shift()\n }\n\n if (val?.value != null) {\n this.size -= this.calculateSize(val.value)\n }\n\n return val\n }\n\n isEmpty (): boolean {\n return this.head.isEmpty()\n }\n}\n", "/**\n * @packageDocumentation\n *\n * An iterable that you can push values into.\n *\n * @example\n *\n * ```js\n * import { pushable } from 'it-pushable'\n *\n * const source = pushable()\n *\n * setTimeout(() => source.push('hello'), 100)\n * setTimeout(() => source.push('world'), 200)\n * setTimeout(() => source.end(), 300)\n *\n * const start = Date.now()\n *\n * for await (const value of source) {\n * console.log(`got \"${value}\" after ${Date.now() - start}ms`)\n * }\n * console.log(`done after ${Date.now() - start}ms`)\n *\n * // Output:\n * // got \"hello\" after 105ms\n * // got \"world\" after 207ms\n * // done after 309ms\n * ```\n *\n * @example\n *\n * ```js\n * import { pushableV } from 'it-pushable'\n * import all from 'it-all'\n *\n * const source = pushableV()\n *\n * source.push(1)\n * source.push(2)\n * source.push(3)\n * source.end()\n *\n * console.info(await all(source))\n *\n * // Output:\n * // [ [1, 2, 3] ]\n * ```\n */\n\nimport deferred from 'p-defer'\nimport { FIFO, type Next } from './fifo.js'\n\nexport class AbortError extends Error {\n type: string\n code: string\n\n constructor (message?: string, code?: string) {\n super(message ?? 'The operation was aborted')\n this.type = 'aborted'\n this.code = code ?? 'ABORT_ERR'\n }\n}\n\nexport interface AbortOptions {\n signal?: AbortSignal\n}\n\ninterface BasePushable<T> {\n /**\n * End the iterable after all values in the buffer (if any) have been yielded. If an\n * error is passed the buffer is cleared immediately and the next iteration will\n * throw the passed error\n */\n end(err?: Error): this\n\n /**\n * Push a value into the iterable. Values are yielded from the iterable in the order\n * they are pushed. Values not yet consumed from the iterable are buffered.\n */\n push(value: T): this\n\n /**\n * Returns a promise that resolves when the underlying queue becomes empty (e.g.\n * this.readableLength === 0).\n *\n * If an AbortSignal is passed as an option and that signal aborts, it only\n * causes the returned promise to reject - it does not end the pushable.\n */\n onEmpty(options?: AbortOptions): Promise<void>\n\n /**\n * This property contains the number of bytes (or objects) in the queue ready to be read.\n *\n * If `objectMode` is true, this is the number of objects in the queue, if false it's the\n * total number of bytes in the queue.\n */\n readableLength: number\n}\n\n/**\n * An iterable that you can push values into.\n */\nexport interface Pushable<T, R = void, N = unknown> extends AsyncGenerator<T, R, N>, BasePushable<T> {}\n\n/**\n * Similar to `pushable`, except it yields multiple buffered chunks at a time. All values yielded from the iterable will be arrays.\n */\nexport interface PushableV<T, R = void, N = unknown> extends AsyncGenerator<T[], R, N>, BasePushable<T> {}\n\nexport interface Options {\n /**\n * A boolean value that means non-`Uint8Array`s will be passed to `.push`, default: `false`\n */\n objectMode?: boolean\n\n /**\n * A function called after *all* values have been yielded from the iterator (including\n * buffered values). In the case when the iterator is ended with an error it will be\n * passed the error as a parameter.\n */\n onEnd?(err?: Error): void\n}\n\nexport interface DoneResult { done: true }\nexport interface ValueResult<T> { done: false, value: T }\nexport type NextResult<T> = ValueResult<T> | DoneResult\n\ninterface getNext<T, V = T> { (buffer: FIFO<T>): NextResult<V> }\n\nexport interface ObjectPushableOptions extends Options {\n objectMode: true\n}\n\nexport interface BytePushableOptions extends Options {\n objectMode?: false\n}\n\n/**\n * Create a new async iterable. The values yielded from calls to `.next()`\n * or when used in a `for await of`loop are \"pushed\" into the iterable.\n * Returns an async iterable object with additional methods.\n */\nexport function pushable<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): Pushable<T>\nexport function pushable<T> (options: ObjectPushableOptions): Pushable<T>\nexport function pushable<T> (options: Options = {}): Pushable<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T> => {\n const next: Next<T> | undefined = buffer.shift()\n\n if (next == null) {\n return { done: true }\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n return {\n done: next.done === true,\n // @ts-expect-error if done is false, value will be present\n value: next.value\n }\n }\n\n return _pushable<T, T, Pushable<T>>(getNext, options)\n}\n\nexport function pushableV<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): PushableV<T>\nexport function pushableV<T> (options: ObjectPushableOptions): PushableV<T>\nexport function pushableV<T> (options: Options = {}): PushableV<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T[]> => {\n let next: Next<T> | undefined\n const values: T[] = []\n\n while (!buffer.isEmpty()) {\n next = buffer.shift()\n\n if (next == null) {\n break\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n if (next.done === false) {\n // @ts-expect-error if done is false value should be pushed\n values.push(next.value)\n }\n }\n\n if (next == null) {\n return { done: true }\n }\n\n return {\n done: next.done === true,\n value: values\n }\n }\n\n return _pushable<T, T[], PushableV<T>>(getNext, options)\n}\n\nfunction _pushable<PushType, ValueType, ReturnType> (getNext: getNext<PushType, ValueType>, options?: Options): ReturnType {\n options = options ?? {}\n let onEnd = options.onEnd\n let buffer = new FIFO<PushType>()\n let pushable: any\n let onNext: ((next: Next<PushType>) => ReturnType) | null\n let ended: boolean\n let drain = deferred()\n\n const waitNext = async (): Promise<NextResult<ValueType>> => {\n try {\n if (!buffer.isEmpty()) {\n return getNext(buffer)\n }\n\n if (ended) {\n return { done: true }\n }\n\n return await new Promise<NextResult<ValueType>>((resolve, reject) => {\n onNext = (next: Next<PushType>) => {\n onNext = null\n buffer.push(next)\n\n try {\n resolve(getNext(buffer))\n } catch (err) {\n reject(err)\n }\n\n return pushable\n }\n })\n } finally {\n if (buffer.isEmpty()) {\n // settle promise in the microtask queue to give consumers a chance to\n // await after calling .push\n queueMicrotask(() => {\n drain.resolve()\n drain = deferred()\n })\n }\n }\n }\n\n const bufferNext = (next: Next<PushType>): ReturnType => {\n if (onNext != null) {\n return onNext(next)\n }\n\n buffer.push(next)\n return pushable\n }\n\n const bufferError = (err: Error): ReturnType => {\n buffer = new FIFO()\n\n if (onNext != null) {\n return onNext({ error: err })\n }\n\n buffer.push({ error: err })\n return pushable\n }\n\n const push = (value: PushType): ReturnType => {\n if (ended) {\n return pushable\n }\n\n // @ts-expect-error `byteLength` is not declared on PushType\n if (options?.objectMode !== true && value?.byteLength == null) {\n throw new Error('objectMode was not true but tried to push non-Uint8Array value')\n }\n\n return bufferNext({ done: false, value })\n }\n const end = (err?: Error): ReturnType => {\n if (ended) return pushable\n ended = true\n\n return (err != null) ? bufferError(err) : bufferNext({ done: true })\n }\n const _return = (): DoneResult => {\n buffer = new FIFO()\n end()\n\n return { done: true }\n }\n const _throw = (err: Error): DoneResult => {\n end(err)\n\n return { done: true }\n }\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next: waitNext,\n return: _return,\n throw: _throw,\n push,\n end,\n get readableLength (): number {\n return buffer.size\n },\n onEmpty: async (options?: AbortOptions) => {\n const signal = options?.signal\n signal?.throwIfAborted()\n\n if (buffer.isEmpty()) {\n return\n }\n\n let cancel: Promise<void> | undefined\n let listener: (() => void) | undefined\n\n if (signal != null) {\n cancel = new Promise((resolve, reject) => {\n listener = () => {\n reject(new AbortError())\n }\n\n signal.addEventListener('abort', listener)\n })\n }\n\n try {\n await Promise.race([\n drain.promise,\n cancel\n ])\n } finally {\n if (listener != null && signal != null) {\n signal?.removeEventListener('abort', listener)\n }\n }\n }\n }\n\n if (onEnd == null) {\n return pushable\n }\n\n const _pushable = pushable\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next () {\n return _pushable.next()\n },\n throw (err: Error) {\n _pushable.throw(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return { done: true }\n },\n return () {\n _pushable.return()\n\n if (onEnd != null) {\n onEnd()\n onEnd = undefined\n }\n\n return { done: true }\n },\n push,\n end (err: Error) {\n _pushable.end(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return pushable\n },\n get readableLength () {\n return _pushable.readableLength\n },\n onEmpty: (opts?: AbortOptions) => {\n return _pushable.onEmpty(opts)\n }\n }\n\n return pushable\n}\n", "export const PROTOCOL_NAME = '/perf/1.0.0'\nexport const WRITE_BLOCK_SIZE = 64 << 10\nexport const MAX_INBOUND_STREAMS = 1\nexport const MAX_OUTBOUND_STREAMS = 1\nexport const RUN_ON_LIMITED_CONNECTION = false\n", "import { pushable } from 'it-pushable'\nimport { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'\nimport type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js'\nimport type { Logger, Startable, IncomingStreamData } from '@libp2p/interface'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport class Perf implements Startable, PerfInterface {\n private readonly log: Logger\n public readonly protocol: string\n private readonly components: PerfComponents\n private started: boolean\n private readonly buf: ArrayBuffer\n private readonly writeBlockSize: number\n private readonly maxInboundStreams: number\n private readonly maxOutboundStreams: number\n private readonly runOnLimitedConnection: boolean\n\n constructor (components: PerfComponents, init: PerfInit = {}) {\n this.components = components\n this.log = components.logger.forComponent('libp2p:perf')\n this.started = false\n this.protocol = init.protocolName ?? PROTOCOL_NAME\n this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE\n this.buf = new ArrayBuffer(this.writeBlockSize)\n this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS\n this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS\n this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION\n }\n\n readonly [Symbol.toStringTag] = '@libp2p/perf'\n\n async start (): Promise<void> {\n await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {\n void this.handleMessage(data).catch((err) => {\n this.log.error('error handling perf protocol message', err)\n })\n }, {\n maxInboundStreams: this.maxInboundStreams,\n maxOutboundStreams: this.maxOutboundStreams,\n runOnLimitedConnection: this.runOnLimitedConnection\n })\n this.started = true\n }\n\n async stop (): Promise<void> {\n await this.components.registrar.unhandle(this.protocol)\n this.started = false\n }\n\n isStarted (): boolean {\n return this.started\n }\n\n async handleMessage (data: IncomingStreamData): Promise<void> {\n const { stream } = data\n\n try {\n const writeBlockSize = this.writeBlockSize\n\n let bytesToSendBack: number | undefined\n\n for await (const buf of stream.source) {\n if (bytesToSendBack == null) {\n // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty\n bytesToSendBack = Number(buf.getBigUint64(0, false))\n }\n\n // Ingest all the data and wait for the read side to close\n }\n\n if (bytesToSendBack == null) {\n throw new Error('bytesToSendBack was not set')\n }\n\n const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength)\n\n await stream.sink(async function * () {\n while (bytesToSendBack > 0) {\n let toSend: number = writeBlockSize\n if (toSend > bytesToSendBack) {\n toSend = bytesToSendBack\n }\n\n bytesToSendBack = bytesToSendBack - toSend\n yield uint8Buf.subarray(0, toSend)\n }\n }())\n } catch (err: any) {\n stream.abort(err)\n }\n }\n\n async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {\n this.log('opening stream on protocol %s to %a', this.protocol, ma)\n\n const uint8Buf = new Uint8Array(this.buf)\n const writeBlockSize = this.writeBlockSize\n\n const initialStartTime = Date.now()\n let lastReportedTime = Date.now()\n const connection = await this.components.connectionManager.openConnection(ma, {\n ...options,\n force: options.reuseExistingConnection !== true\n })\n\n this.log('opened connection after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n const stream = await connection.newStream(this.protocol, options)\n\n this.log('opened stream after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n let lastAmountOfBytesSent = 0\n let totalBytesSent = 0\n const uploadStart = Date.now()\n\n // tell the remote how many bytes we will send. Up cast to 64 bit number\n // as if we send as ui32 we limit total transfer size to 4GB\n const view = new DataView(this.buf)\n view.setBigUint64(0, BigInt(receiveBytes), false)\n\n this.log('sending %i bytes to %p', sendBytes, connection.remotePeer)\n\n try {\n const output = pushable<PerfOutput>({\n objectMode: true\n })\n\n stream.sink(async function * () {\n yield uint8Buf.subarray(0, 8)\n\n while (sendBytes > 0) {\n let toSend: number = writeBlockSize\n\n if (toSend > sendBytes) {\n toSend = sendBytes\n }\n\n yield uint8Buf.subarray(0, toSend)\n\n sendBytes -= toSend\n\n if (Date.now() - lastReportedTime > 1000) {\n output.push({\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: lastAmountOfBytesSent,\n downloadBytes: 0\n })\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesSent = 0\n }\n\n lastAmountOfBytesSent += toSend\n totalBytesSent += toSend\n }\n\n output.end()\n }())\n .catch(err => {\n output.end(err)\n })\n\n yield * output\n\n this.log('upload complete after %d ms', Date.now() - uploadStart)\n\n // Read the received bytes\n let lastAmountOfBytesReceived = 0\n lastReportedTime = Date.now()\n let totalBytesReceived = 0\n const downloadStart = Date.now()\n\n for await (const buf of stream.source) {\n if (Date.now() - lastReportedTime > 1000) {\n yield {\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: 0,\n downloadBytes: lastAmountOfBytesReceived\n }\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesReceived = 0\n }\n\n lastAmountOfBytesReceived += buf.byteLength\n totalBytesReceived += buf.byteLength\n }\n\n this.log('download complete after %d ms', Date.now() - downloadStart)\n\n if (totalBytesReceived !== receiveBytes) {\n throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)\n }\n\n yield {\n type: 'final',\n timeSeconds: (Date.now() - initialStartTime) / 1000,\n uploadBytes: totalBytesSent,\n downloadBytes: totalBytesReceived\n }\n\n this.log('performed %s to %p', this.protocol, connection.remotePeer)\n await stream.close()\n } catch (err: any) {\n this.log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)\n stream.abort(err)\n throw err\n }\n }\n}\n"],
|
5
|
-
"mappings": "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
|
6
|
-
"names": ["index_exports", "__export", "perf", "pDefer", "deferred", "resolve", "reject", "FixedFIFO", "hwm", "data", "last", "FIFO", "options", "obj", "val", "prev", "next", "AbortError", "message", "code", "pushable", "options", "_pushable", "buffer", "next", "_pushable", "getNext", "options", "onEnd", "buffer", "FIFO", "pushable", "onNext", "ended", "drain", "pDefer", "waitNext", "resolve", "reject", "next", "err", "bufferNext", "bufferError", "push", "value", "end", "_return", "_throw", "signal", "cancel", "listener", "AbortError", "opts", "PROTOCOL_NAME", "Perf", "components", "init", "PROTOCOL_NAME", "data", "err", "stream", "writeBlockSize", "bytesToSendBack", "buf", "uint8Buf", "toSend", "ma", "sendBytes", "receiveBytes", "options", "initialStartTime", "lastReportedTime", "connection", "lastAmountOfBytesSent", "totalBytesSent", "uploadStart", "output", "pushable", "lastAmountOfBytesReceived", "totalBytesReceived", "downloadStart", "perf", "init", "components", "Perf"]
|
4
|
+
"sourcesContent": ["/**\n * @packageDocumentation\n *\n * The {@link Perf} service implements the [perf protocol](https://github.com/libp2p/specs/blob/master/perf/perf.md), which can be used to measure transfer performance within and across libp2p implementations.\n *\n * @example\n *\n * ```typescript\n * import { noise } from '@chainsafe/libp2p-noise'\n * import { yamux } from '@chainsafe/libp2p-yamux'\n * import { tcp } from '@libp2p/tcp'\n * import { createLibp2p, type Libp2p } from 'libp2p'\n * import { plaintext } from '@libp2p/plaintext'\n * import { perf, type Perf } from '@libp2p/perf'\n *\n * const ONE_MEG = 1024 * 1024\n * const UPLOAD_BYTES = ONE_MEG * 1024\n * const DOWNLOAD_BYTES = ONE_MEG * 1024\n *\n * async function createNode (): Promise<Libp2p<{ perf: Perf }>> {\n * return createLibp2p({\n * addresses: {\n * listen: [\n * '/ip4/0.0.0.0/tcp/0'\n * ]\n * },\n * transports: [\n * tcp()\n * ],\n * connectionEncrypters: [\n * noise(), plaintext()\n * ],\n * streamMuxers: [\n * yamux()\n * ],\n * services: {\n * perf: perf()\n * }\n * })\n * }\n *\n * const libp2p1 = await createNode()\n * const libp2p2 = await createNode()\n *\n * for await (const output of libp2p1.services.perf.measurePerformance(libp2p2.getMultiaddrs()[0], UPLOAD_BYTES, DOWNLOAD_BYTES)) {\n * console.info(output)\n * }\n *\n * await libp2p1.stop()\n * await libp2p2.stop()\n * ```\n */\n\nimport { Perf as PerfClass } from './perf-service.js'\nimport type { AbortOptions, ComponentLogger } from '@libp2p/interface'\nimport type { ConnectionManager, Registrar } from '@libp2p/interface-internal'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport interface PerfOptions extends AbortOptions {\n /**\n * By default measuring perf should include the time it takes to establish a\n * connection, so a new connection will be opened for every performance run.\n *\n * To override this and re-use an existing connection if one is present, pass\n * `true` here.\n *\n * @default false\n */\n reuseExistingConnection?: boolean\n}\n\nexport interface Perf {\n measurePerformance(multiaddr: Multiaddr, sendBytes: number, recvBytes: number, options?: PerfOptions): AsyncGenerator<PerfOutput>\n}\n\nexport interface PerfOutput {\n type: 'connection' | 'stream' | 'intermediary' | 'final'\n timeSeconds: number\n uploadBytes: number\n downloadBytes: number\n}\n\nexport interface PerfInit {\n protocolName?: string\n maxInboundStreams?: number\n maxOutboundStreams?: number\n runOnLimitedConnection?: boolean\n\n /**\n * Data sent/received will be sent in chunks of this size\n *\n * @default 65536\n */\n writeBlockSize?: number\n}\n\nexport interface PerfComponents {\n registrar: Registrar\n connectionManager: ConnectionManager\n logger: ComponentLogger\n}\n\nexport function perf (init: PerfInit = {}): (components: PerfComponents) => Perf {\n return (components) => new PerfClass(components, init)\n}\n", "export default function pDefer() {\n\tconst deferred = {};\n\n\tdeferred.promise = new Promise((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\n\treturn deferred;\n}\n", "// ported from https://www.npmjs.com/package/fast-fifo\n\nexport interface Next<T> {\n done?: boolean\n error?: Error\n value?: T\n}\n\nclass FixedFIFO<T> {\n public buffer: Array<Next<T> | undefined>\n private readonly mask: number\n private top: number\n private btm: number\n public next: FixedFIFO<T> | null\n\n constructor (hwm: number) {\n if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) {\n throw new Error('Max size for a FixedFIFO should be a power of two')\n }\n\n this.buffer = new Array(hwm)\n this.mask = hwm - 1\n this.top = 0\n this.btm = 0\n this.next = null\n }\n\n push (data: Next<T>): boolean {\n if (this.buffer[this.top] !== undefined) {\n return false\n }\n\n this.buffer[this.top] = data\n this.top = (this.top + 1) & this.mask\n\n return true\n }\n\n shift (): Next<T> | undefined {\n const last = this.buffer[this.btm]\n\n if (last === undefined) {\n return undefined\n }\n\n this.buffer[this.btm] = undefined\n this.btm = (this.btm + 1) & this.mask\n return last\n }\n\n isEmpty (): boolean {\n return this.buffer[this.btm] === undefined\n }\n}\n\nexport interface FIFOOptions {\n /**\n * When the queue reaches this size, it will be split into head/tail parts\n */\n splitLimit?: number\n}\n\nexport class FIFO<T> {\n public size: number\n private readonly hwm: number\n private head: FixedFIFO<T>\n private tail: FixedFIFO<T>\n\n constructor (options: FIFOOptions = {}) {\n this.hwm = options.splitLimit ?? 16\n this.head = new FixedFIFO<T>(this.hwm)\n this.tail = this.head\n this.size = 0\n }\n\n calculateSize (obj: any): number {\n if (obj?.byteLength != null) {\n return obj.byteLength\n }\n\n return 1\n }\n\n push (val: Next<T>): void {\n if (val?.value != null) {\n this.size += this.calculateSize(val.value)\n }\n\n if (!this.head.push(val)) {\n const prev = this.head\n this.head = prev.next = new FixedFIFO<T>(2 * this.head.buffer.length)\n this.head.push(val)\n }\n }\n\n shift (): Next<T> | undefined {\n let val = this.tail.shift()\n\n if (val === undefined && (this.tail.next != null)) {\n const next = this.tail.next\n this.tail.next = null\n this.tail = next\n val = this.tail.shift()\n }\n\n if (val?.value != null) {\n this.size -= this.calculateSize(val.value)\n }\n\n return val\n }\n\n isEmpty (): boolean {\n return this.head.isEmpty()\n }\n}\n", "/**\n * @packageDocumentation\n *\n * An iterable that you can push values into.\n *\n * @example\n *\n * ```js\n * import { pushable } from 'it-pushable'\n *\n * const source = pushable()\n *\n * setTimeout(() => source.push('hello'), 100)\n * setTimeout(() => source.push('world'), 200)\n * setTimeout(() => source.end(), 300)\n *\n * const start = Date.now()\n *\n * for await (const value of source) {\n * console.log(`got \"${value}\" after ${Date.now() - start}ms`)\n * }\n * console.log(`done after ${Date.now() - start}ms`)\n *\n * // Output:\n * // got \"hello\" after 105ms\n * // got \"world\" after 207ms\n * // done after 309ms\n * ```\n *\n * @example\n *\n * ```js\n * import { pushableV } from 'it-pushable'\n * import all from 'it-all'\n *\n * const source = pushableV()\n *\n * source.push(1)\n * source.push(2)\n * source.push(3)\n * source.end()\n *\n * console.info(await all(source))\n *\n * // Output:\n * // [ [1, 2, 3] ]\n * ```\n */\n\nimport deferred from 'p-defer'\nimport { FIFO, type Next } from './fifo.js'\n\nexport class AbortError extends Error {\n type: string\n code: string\n\n constructor (message?: string, code?: string) {\n super(message ?? 'The operation was aborted')\n this.type = 'aborted'\n this.code = code ?? 'ABORT_ERR'\n }\n}\n\nexport interface AbortOptions {\n signal?: AbortSignal\n}\n\ninterface BasePushable<T> {\n /**\n * End the iterable after all values in the buffer (if any) have been yielded. If an\n * error is passed the buffer is cleared immediately and the next iteration will\n * throw the passed error\n */\n end(err?: Error): this\n\n /**\n * Push a value into the iterable. Values are yielded from the iterable in the order\n * they are pushed. Values not yet consumed from the iterable are buffered.\n */\n push(value: T): this\n\n /**\n * Returns a promise that resolves when the underlying queue becomes empty (e.g.\n * this.readableLength === 0).\n *\n * If an AbortSignal is passed as an option and that signal aborts, it only\n * causes the returned promise to reject - it does not end the pushable.\n */\n onEmpty(options?: AbortOptions): Promise<void>\n\n /**\n * This property contains the number of bytes (or objects) in the queue ready to be read.\n *\n * If `objectMode` is true, this is the number of objects in the queue, if false it's the\n * total number of bytes in the queue.\n */\n readableLength: number\n}\n\n/**\n * An iterable that you can push values into.\n */\nexport interface Pushable<T, R = void, N = unknown> extends AsyncGenerator<T, R, N>, BasePushable<T> {}\n\n/**\n * Similar to `pushable`, except it yields multiple buffered chunks at a time. All values yielded from the iterable will be arrays.\n */\nexport interface PushableV<T, R = void, N = unknown> extends AsyncGenerator<T[], R, N>, BasePushable<T> {}\n\nexport interface Options {\n /**\n * A boolean value that means non-`Uint8Array`s will be passed to `.push`, default: `false`\n */\n objectMode?: boolean\n\n /**\n * A function called after *all* values have been yielded from the iterator (including\n * buffered values). In the case when the iterator is ended with an error it will be\n * passed the error as a parameter.\n */\n onEnd?(err?: Error): void\n}\n\nexport interface DoneResult { done: true }\nexport interface ValueResult<T> { done: false, value: T }\nexport type NextResult<T> = ValueResult<T> | DoneResult\n\ninterface getNext<T, V = T> { (buffer: FIFO<T>): NextResult<V> }\n\nexport interface ObjectPushableOptions extends Options {\n objectMode: true\n}\n\nexport interface BytePushableOptions extends Options {\n objectMode?: false\n}\n\n/**\n * Create a new async iterable. The values yielded from calls to `.next()`\n * or when used in a `for await of`loop are \"pushed\" into the iterable.\n * Returns an async iterable object with additional methods.\n */\nexport function pushable<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): Pushable<T>\nexport function pushable<T> (options: ObjectPushableOptions): Pushable<T>\nexport function pushable<T> (options: Options = {}): Pushable<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T> => {\n const next: Next<T> | undefined = buffer.shift()\n\n if (next == null) {\n return { done: true }\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n return {\n done: next.done === true,\n // @ts-expect-error if done is false, value will be present\n value: next.value\n }\n }\n\n return _pushable<T, T, Pushable<T>>(getNext, options)\n}\n\nexport function pushableV<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): PushableV<T>\nexport function pushableV<T> (options: ObjectPushableOptions): PushableV<T>\nexport function pushableV<T> (options: Options = {}): PushableV<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T[]> => {\n let next: Next<T> | undefined\n const values: T[] = []\n\n while (!buffer.isEmpty()) {\n next = buffer.shift()\n\n if (next == null) {\n break\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n if (next.done === false) {\n // @ts-expect-error if done is false value should be pushed\n values.push(next.value)\n }\n }\n\n if (next == null) {\n return { done: true }\n }\n\n return {\n done: next.done === true,\n value: values\n }\n }\n\n return _pushable<T, T[], PushableV<T>>(getNext, options)\n}\n\nfunction _pushable<PushType, ValueType, ReturnType> (getNext: getNext<PushType, ValueType>, options?: Options): ReturnType {\n options = options ?? {}\n let onEnd = options.onEnd\n let buffer = new FIFO<PushType>()\n let pushable: any\n let onNext: ((next: Next<PushType>) => ReturnType) | null\n let ended: boolean\n let drain = deferred()\n\n const waitNext = async (): Promise<NextResult<ValueType>> => {\n try {\n if (!buffer.isEmpty()) {\n return getNext(buffer)\n }\n\n if (ended) {\n return { done: true }\n }\n\n return await new Promise<NextResult<ValueType>>((resolve, reject) => {\n onNext = (next: Next<PushType>) => {\n onNext = null\n buffer.push(next)\n\n try {\n resolve(getNext(buffer))\n } catch (err) {\n reject(err)\n }\n\n return pushable\n }\n })\n } finally {\n if (buffer.isEmpty()) {\n // settle promise in the microtask queue to give consumers a chance to\n // await after calling .push\n queueMicrotask(() => {\n drain.resolve()\n drain = deferred()\n })\n }\n }\n }\n\n const bufferNext = (next: Next<PushType>): ReturnType => {\n if (onNext != null) {\n return onNext(next)\n }\n\n buffer.push(next)\n return pushable\n }\n\n const bufferError = (err: Error): ReturnType => {\n buffer = new FIFO()\n\n if (onNext != null) {\n return onNext({ error: err })\n }\n\n buffer.push({ error: err })\n return pushable\n }\n\n const push = (value: PushType): ReturnType => {\n if (ended) {\n return pushable\n }\n\n // @ts-expect-error `byteLength` is not declared on PushType\n if (options?.objectMode !== true && value?.byteLength == null) {\n throw new Error('objectMode was not true but tried to push non-Uint8Array value')\n }\n\n return bufferNext({ done: false, value })\n }\n const end = (err?: Error): ReturnType => {\n if (ended) return pushable\n ended = true\n\n return (err != null) ? bufferError(err) : bufferNext({ done: true })\n }\n const _return = (): DoneResult => {\n buffer = new FIFO()\n end()\n\n return { done: true }\n }\n const _throw = (err: Error): DoneResult => {\n end(err)\n\n return { done: true }\n }\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next: waitNext,\n return: _return,\n throw: _throw,\n push,\n end,\n get readableLength (): number {\n return buffer.size\n },\n onEmpty: async (options?: AbortOptions) => {\n const signal = options?.signal\n signal?.throwIfAborted()\n\n if (buffer.isEmpty()) {\n return\n }\n\n let cancel: Promise<void> | undefined\n let listener: (() => void) | undefined\n\n if (signal != null) {\n cancel = new Promise((resolve, reject) => {\n listener = () => {\n reject(new AbortError())\n }\n\n signal.addEventListener('abort', listener)\n })\n }\n\n try {\n await Promise.race([\n drain.promise,\n cancel\n ])\n } finally {\n if (listener != null && signal != null) {\n signal?.removeEventListener('abort', listener)\n }\n }\n }\n }\n\n if (onEnd == null) {\n return pushable\n }\n\n const _pushable = pushable\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next () {\n return _pushable.next()\n },\n throw (err: Error) {\n _pushable.throw(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return { done: true }\n },\n return () {\n _pushable.return()\n\n if (onEnd != null) {\n onEnd()\n onEnd = undefined\n }\n\n return { done: true }\n },\n push,\n end (err: Error) {\n _pushable.end(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return pushable\n },\n get readableLength () {\n return _pushable.readableLength\n },\n onEmpty: (opts?: AbortOptions) => {\n return _pushable.onEmpty(opts)\n }\n }\n\n return pushable\n}\n", "export const PROTOCOL_NAME = '/perf/1.0.0'\nexport const WRITE_BLOCK_SIZE = 64 << 10\nexport const MAX_INBOUND_STREAMS = 1\nexport const MAX_OUTBOUND_STREAMS = 1\nexport const RUN_ON_LIMITED_CONNECTION = false\n", "import { pushable } from 'it-pushable'\nimport { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'\nimport type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js'\nimport type { Logger, Startable, IncomingStreamData } from '@libp2p/interface'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport class Perf implements Startable, PerfInterface {\n private readonly log: Logger\n public readonly protocol: string\n private readonly components: PerfComponents\n private started: boolean\n private readonly buf: ArrayBuffer\n private readonly writeBlockSize: number\n private readonly maxInboundStreams: number\n private readonly maxOutboundStreams: number\n private readonly runOnLimitedConnection: boolean\n\n constructor (components: PerfComponents, init: PerfInit = {}) {\n this.components = components\n this.log = components.logger.forComponent('libp2p:perf')\n this.started = false\n this.protocol = init.protocolName ?? PROTOCOL_NAME\n this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE\n this.buf = new ArrayBuffer(this.writeBlockSize)\n this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS\n this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS\n this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION\n }\n\n readonly [Symbol.toStringTag] = '@libp2p/perf'\n\n async start (): Promise<void> {\n await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {\n void this.handleMessage(data).catch((err) => {\n this.log.error('error handling perf protocol message - %e', err)\n })\n }, {\n maxInboundStreams: this.maxInboundStreams,\n maxOutboundStreams: this.maxOutboundStreams,\n runOnLimitedConnection: this.runOnLimitedConnection\n })\n this.started = true\n }\n\n async stop (): Promise<void> {\n await this.components.registrar.unhandle(this.protocol)\n this.started = false\n }\n\n isStarted (): boolean {\n return this.started\n }\n\n async handleMessage (data: IncomingStreamData): Promise<void> {\n const { stream } = data\n\n try {\n const writeBlockSize = this.writeBlockSize\n\n let bytesToSendBack: number | undefined\n\n for await (const buf of stream.source) {\n if (bytesToSendBack == null) {\n // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty\n bytesToSendBack = Number(buf.getBigUint64(0, false))\n }\n\n // Ingest all the data and wait for the read side to close\n }\n\n if (bytesToSendBack == null) {\n throw new Error('bytesToSendBack was not set')\n }\n\n const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength)\n\n await stream.sink(async function * () {\n while (bytesToSendBack > 0) {\n let toSend: number = writeBlockSize\n if (toSend > bytesToSendBack) {\n toSend = bytesToSendBack\n }\n\n bytesToSendBack = bytesToSendBack - toSend\n yield uint8Buf.subarray(0, toSend)\n }\n }())\n } catch (err: any) {\n stream.abort(err)\n }\n }\n\n async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {\n const uint8Buf = new Uint8Array(this.buf)\n const writeBlockSize = this.writeBlockSize\n\n const initialStartTime = Date.now()\n let lastReportedTime = Date.now()\n const connection = await this.components.connectionManager.openConnection(ma, {\n ...options,\n force: options.reuseExistingConnection !== true\n })\n\n const log = connection.log.newScope('perf')\n\n log('opened connection after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n const stream = await connection.newStream(this.protocol, options)\n\n log('opened stream after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n let lastAmountOfBytesSent = 0\n let totalBytesSent = 0\n const uploadStart = Date.now()\n\n // tell the remote how many bytes we will send. Up cast to 64 bit number\n // as if we send as ui32 we limit total transfer size to 4GB\n const view = new DataView(this.buf)\n view.setBigUint64(0, BigInt(receiveBytes), false)\n\n log('sending %i bytes to %p', sendBytes, connection.remotePeer)\n\n try {\n const output = pushable<PerfOutput>({\n objectMode: true\n })\n\n stream.sink(async function * () {\n yield uint8Buf.subarray(0, 8)\n\n while (sendBytes > 0) {\n let toSend: number = writeBlockSize\n\n if (toSend > sendBytes) {\n toSend = sendBytes\n }\n\n yield uint8Buf.subarray(0, toSend)\n\n sendBytes -= toSend\n\n if (Date.now() - lastReportedTime > 1000) {\n output.push({\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: lastAmountOfBytesSent,\n downloadBytes: 0\n })\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesSent = 0\n }\n\n lastAmountOfBytesSent += toSend\n totalBytesSent += toSend\n }\n\n output.end()\n }())\n .catch(err => {\n output.end(err)\n })\n\n yield * output\n\n log('upload complete after %d ms', Date.now() - uploadStart)\n\n // Read the received bytes\n let lastAmountOfBytesReceived = 0\n lastReportedTime = Date.now()\n let totalBytesReceived = 0\n const downloadStart = Date.now()\n\n for await (const buf of stream.source) {\n if (Date.now() - lastReportedTime > 1000) {\n yield {\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: 0,\n downloadBytes: lastAmountOfBytesReceived\n }\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesReceived = 0\n }\n\n lastAmountOfBytesReceived += buf.byteLength\n totalBytesReceived += buf.byteLength\n }\n\n log('download complete after %d ms', Date.now() - downloadStart)\n\n if (totalBytesReceived !== receiveBytes) {\n throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)\n }\n\n yield {\n type: 'final',\n timeSeconds: (Date.now() - initialStartTime) / 1000,\n uploadBytes: totalBytesSent,\n downloadBytes: totalBytesReceived\n }\n\n log('performed %s to %p', this.protocol, connection.remotePeer)\n await stream.close()\n } catch (err: any) {\n log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)\n stream.abort(err)\n throw err\n }\n }\n}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["index_exports", "__export", "perf", "pDefer", "deferred", "resolve", "reject", "FixedFIFO", "hwm", "data", "last", "FIFO", "options", "obj", "val", "prev", "next", "AbortError", "message", "code", "pushable", "options", "_pushable", "buffer", "next", "_pushable", "getNext", "options", "onEnd", "buffer", "FIFO", "pushable", "onNext", "ended", "drain", "pDefer", "waitNext", "resolve", "reject", "next", "err", "bufferNext", "bufferError", "push", "value", "end", "_return", "_throw", "signal", "cancel", "listener", "AbortError", "opts", "PROTOCOL_NAME", "Perf", "components", "init", "PROTOCOL_NAME", "data", "err", "stream", "writeBlockSize", "bytesToSendBack", "buf", "uint8Buf", "toSend", "ma", "sendBytes", "receiveBytes", "options", "initialStartTime", "lastReportedTime", "connection", "log", "lastAmountOfBytesSent", "totalBytesSent", "uploadStart", "output", "pushable", "lastAmountOfBytesReceived", "totalBytesReceived", "downloadStart", "perf", "init", "components", "Perf"]
|
7
7
|
}
|
package/dist/src/perf-service.js
CHANGED
@@ -25,7 +25,7 @@ export class Perf {
|
|
25
25
|
async start() {
|
26
26
|
await this.components.registrar.handle(this.protocol, (data) => {
|
27
27
|
void this.handleMessage(data).catch((err) => {
|
28
|
-
this.log.error('error handling perf protocol message', err);
|
28
|
+
this.log.error('error handling perf protocol message - %e', err);
|
29
29
|
});
|
30
30
|
}, {
|
31
31
|
maxInboundStreams: this.maxInboundStreams,
|
@@ -73,7 +73,6 @@ export class Perf {
|
|
73
73
|
}
|
74
74
|
}
|
75
75
|
async *measurePerformance(ma, sendBytes, receiveBytes, options = {}) {
|
76
|
-
this.log('opening stream on protocol %s to %a', this.protocol, ma);
|
77
76
|
const uint8Buf = new Uint8Array(this.buf);
|
78
77
|
const writeBlockSize = this.writeBlockSize;
|
79
78
|
const initialStartTime = Date.now();
|
@@ -82,10 +81,11 @@ export class Perf {
|
|
82
81
|
...options,
|
83
82
|
force: options.reuseExistingConnection !== true
|
84
83
|
});
|
85
|
-
|
84
|
+
const log = connection.log.newScope('perf');
|
85
|
+
log('opened connection after %d ms', Date.now() - lastReportedTime);
|
86
86
|
lastReportedTime = Date.now();
|
87
87
|
const stream = await connection.newStream(this.protocol, options);
|
88
|
-
|
88
|
+
log('opened stream after %d ms', Date.now() - lastReportedTime);
|
89
89
|
lastReportedTime = Date.now();
|
90
90
|
let lastAmountOfBytesSent = 0;
|
91
91
|
let totalBytesSent = 0;
|
@@ -94,7 +94,7 @@ export class Perf {
|
|
94
94
|
// as if we send as ui32 we limit total transfer size to 4GB
|
95
95
|
const view = new DataView(this.buf);
|
96
96
|
view.setBigUint64(0, BigInt(receiveBytes), false);
|
97
|
-
|
97
|
+
log('sending %i bytes to %p', sendBytes, connection.remotePeer);
|
98
98
|
try {
|
99
99
|
const output = pushable({
|
100
100
|
objectMode: true
|
@@ -129,7 +129,7 @@ export class Perf {
|
|
129
129
|
output.end(err);
|
130
130
|
});
|
131
131
|
yield* output;
|
132
|
-
|
132
|
+
log('upload complete after %d ms', Date.now() - uploadStart);
|
133
133
|
// Read the received bytes
|
134
134
|
let lastAmountOfBytesReceived = 0;
|
135
135
|
lastReportedTime = Date.now();
|
@@ -151,7 +151,7 @@ export class Perf {
|
|
151
151
|
lastAmountOfBytesReceived += buf.byteLength;
|
152
152
|
totalBytesReceived += buf.byteLength;
|
153
153
|
}
|
154
|
-
|
154
|
+
log('download complete after %d ms', Date.now() - downloadStart);
|
155
155
|
if (totalBytesReceived !== receiveBytes) {
|
156
156
|
throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`);
|
157
157
|
}
|
@@ -161,11 +161,11 @@ export class Perf {
|
|
161
161
|
uploadBytes: totalBytesSent,
|
162
162
|
downloadBytes: totalBytesReceived
|
163
163
|
};
|
164
|
-
|
164
|
+
log('performed %s to %p', this.protocol, connection.remotePeer);
|
165
165
|
await stream.close();
|
166
166
|
}
|
167
167
|
catch (err) {
|
168
|
-
|
168
|
+
log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err);
|
169
169
|
stream.abort(err);
|
170
170
|
throw err;
|
171
171
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"perf-service.js","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,aAAa,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAKtI,MAAM,OAAO,IAAI;IACE,GAAG,CAAQ;IACZ,QAAQ,CAAQ;IACf,UAAU,CAAgB;IACnC,OAAO,CAAS;IACP,GAAG,CAAa;IAChB,cAAc,CAAQ;IACtB,iBAAiB,CAAQ;IACzB,kBAAkB,CAAQ;IAC1B,sBAAsB,CAAS;IAEhD,YAAa,UAA0B,EAAE,OAAiB,EAAE;QAC1D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QACxD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,IAAI,aAAa,CAAA;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,gBAAgB,CAAA;QAC7D,IAAI,CAAC,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC/C,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,mBAAmB,CAAA;QACtE,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,oBAAoB,CAAA;QACzE,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,IAAI,yBAAyB,CAAA;IACxF,CAAC;IAEQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,cAAc,CAAA;IAE9C,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAwB,EAAE,EAAE;YACjF,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,
|
1
|
+
{"version":3,"file":"perf-service.js","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@libp2p/perf",
|
3
|
-
"version": "4.0.
|
3
|
+
"version": "4.0.46-79473c99a",
|
4
4
|
"description": "Implementation of Perf Protocol",
|
5
5
|
"author": "@maschad / @marcopolo",
|
6
6
|
"license": "Apache-2.0 OR MIT",
|
@@ -45,14 +45,14 @@
|
|
45
45
|
"doc-check": "aegir doc-check"
|
46
46
|
},
|
47
47
|
"dependencies": {
|
48
|
-
"@libp2p/interface": "
|
49
|
-
"@libp2p/interface-internal": "
|
48
|
+
"@libp2p/interface": "2.10.5-79473c99a",
|
49
|
+
"@libp2p/interface-internal": "2.3.18-79473c99a",
|
50
50
|
"@multiformats/multiaddr": "^12.4.4",
|
51
51
|
"it-pushable": "^3.2.3"
|
52
52
|
},
|
53
53
|
"devDependencies": {
|
54
|
-
"@libp2p/interface-compliance-tests": "
|
55
|
-
"@libp2p/logger": "
|
54
|
+
"@libp2p/interface-compliance-tests": "6.4.16-79473c99a",
|
55
|
+
"@libp2p/logger": "5.1.21-79473c99a",
|
56
56
|
"aegir": "^47.0.14",
|
57
57
|
"it-last": "^3.0.8",
|
58
58
|
"it-pair": "^2.0.6",
|
package/src/perf-service.ts
CHANGED
@@ -32,7 +32,7 @@ export class Perf implements Startable, PerfInterface {
|
|
32
32
|
async start (): Promise<void> {
|
33
33
|
await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {
|
34
34
|
void this.handleMessage(data).catch((err) => {
|
35
|
-
this.log.error('error handling perf protocol message', err)
|
35
|
+
this.log.error('error handling perf protocol message - %e', err)
|
36
36
|
})
|
37
37
|
}, {
|
38
38
|
maxInboundStreams: this.maxInboundStreams,
|
@@ -91,8 +91,6 @@ export class Perf implements Startable, PerfInterface {
|
|
91
91
|
}
|
92
92
|
|
93
93
|
async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {
|
94
|
-
this.log('opening stream on protocol %s to %a', this.protocol, ma)
|
95
|
-
|
96
94
|
const uint8Buf = new Uint8Array(this.buf)
|
97
95
|
const writeBlockSize = this.writeBlockSize
|
98
96
|
|
@@ -103,12 +101,14 @@ export class Perf implements Startable, PerfInterface {
|
|
103
101
|
force: options.reuseExistingConnection !== true
|
104
102
|
})
|
105
103
|
|
106
|
-
|
104
|
+
const log = connection.log.newScope('perf')
|
105
|
+
|
106
|
+
log('opened connection after %d ms', Date.now() - lastReportedTime)
|
107
107
|
lastReportedTime = Date.now()
|
108
108
|
|
109
109
|
const stream = await connection.newStream(this.protocol, options)
|
110
110
|
|
111
|
-
|
111
|
+
log('opened stream after %d ms', Date.now() - lastReportedTime)
|
112
112
|
lastReportedTime = Date.now()
|
113
113
|
|
114
114
|
let lastAmountOfBytesSent = 0
|
@@ -120,7 +120,7 @@ export class Perf implements Startable, PerfInterface {
|
|
120
120
|
const view = new DataView(this.buf)
|
121
121
|
view.setBigUint64(0, BigInt(receiveBytes), false)
|
122
122
|
|
123
|
-
|
123
|
+
log('sending %i bytes to %p', sendBytes, connection.remotePeer)
|
124
124
|
|
125
125
|
try {
|
126
126
|
const output = pushable<PerfOutput>({
|
@@ -167,7 +167,7 @@ export class Perf implements Startable, PerfInterface {
|
|
167
167
|
|
168
168
|
yield * output
|
169
169
|
|
170
|
-
|
170
|
+
log('upload complete after %d ms', Date.now() - uploadStart)
|
171
171
|
|
172
172
|
// Read the received bytes
|
173
173
|
let lastAmountOfBytesReceived = 0
|
@@ -194,7 +194,7 @@ export class Perf implements Startable, PerfInterface {
|
|
194
194
|
totalBytesReceived += buf.byteLength
|
195
195
|
}
|
196
196
|
|
197
|
-
|
197
|
+
log('download complete after %d ms', Date.now() - downloadStart)
|
198
198
|
|
199
199
|
if (totalBytesReceived !== receiveBytes) {
|
200
200
|
throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)
|
@@ -207,10 +207,10 @@ export class Perf implements Startable, PerfInterface {
|
|
207
207
|
downloadBytes: totalBytesReceived
|
208
208
|
}
|
209
209
|
|
210
|
-
|
210
|
+
log('performed %s to %p', this.protocol, connection.remotePeer)
|
211
211
|
await stream.close()
|
212
212
|
} catch (err: any) {
|
213
|
-
|
213
|
+
log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)
|
214
214
|
stream.abort(err)
|
215
215
|
throw err
|
216
216
|
}
|
package/dist/typedoc-urls.json
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"Perf": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.Perf.html",
|
3
|
-
".:Perf": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.Perf.html",
|
4
|
-
"PerfComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfComponents.html",
|
5
|
-
".:PerfComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfComponents.html",
|
6
|
-
"PerfInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfInit.html",
|
7
|
-
".:PerfInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfInit.html",
|
8
|
-
"PerfOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfOptions.html",
|
9
|
-
".:PerfOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfOptions.html",
|
10
|
-
"PerfOutput": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfOutput.html",
|
11
|
-
".:PerfOutput": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_perf.PerfOutput.html",
|
12
|
-
"perf": "https://libp2p.github.io/js-libp2p/functions/_libp2p_perf.perf.html",
|
13
|
-
".:perf": "https://libp2p.github.io/js-libp2p/functions/_libp2p_perf.perf.html"
|
14
|
-
}
|