From 1317f19a00ae5735ecf8257cf9876d1b38b2228c Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:07:24 +0200 Subject: [PATCH 01/16] fix lint errors in eslint config :) --- .eslintrc.js | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 76da8ea..02825dd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,25 +1,25 @@ module.exports = { - root: true, - "env": { - "commonjs": true, - "es2020": true, - "node": true, - "jasmine": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:jasmine/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 11 - }, - "plugins": ["@typescript-eslint", "jasmine"], - "rules": { - "indent": ["error", 2], - "semi": "error", - "@typescript-eslint/no-var-requires": 0, - "no-constant-condition": 0 - } + root: true, + "env": { + "commonjs": true, + "es2020": true, + "node": true, + "jasmine": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:jasmine/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 11 + }, + "plugins": ["@typescript-eslint", "jasmine"], + "rules": { + "indent": ["error", 2], + "semi": "error", + "@typescript-eslint/no-var-requires": 0, + "no-constant-condition": 0 + } }; From 27bf1be19dff3fb035c6ae6a6c732660247be703 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:07:58 +0200 Subject: [PATCH 02/16] index.d.s: add /* eslint-disable @typescript-eslint/triple-slash-reference */ --- index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.d.ts b/index.d.ts index 6eccc32..086c608 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/triple-slash-reference */ /// /// /// From f55bd66752a379ad59356032a9e0216ddcb2bdf8 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:09:15 +0200 Subject: [PATCH 03/16] improve eslint calling script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c81249..d680859 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "rebuild": "node-gyp rebuild", "clean": "node-gyp clean", "test": "$(npm bin)/jasmine", - "lint": "eslint src examples types --ext .js --ext .ts", + "lint": "eslint . --ext .js --ext .ts", "check-tsc": "./node_modules/.bin/tsc examples/srt.ts --outDir ./tsc-lib", "postversion": "git push && git push --tags" }, From fa09ce31abe4f18c0de3f1fe0ef71948f1e40688 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:13:38 +0200 Subject: [PATCH 04/16] add async-worker version of the SRT JS API with await/Promise support + potentially out-of-order RPC-back/result-dequeuing is possible with a type of call-ID generator and callback-map that we prototyped (but not used atm since the worker is only doing sync/blocking internally with the current SRT lib binding). --- src/async-worker.js | 41 +++++++++ src/async.js | 219 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+) create mode 100644 src/async-worker.js create mode 100644 src/async.js diff --git a/src/async-worker.js b/src/async-worker.js new file mode 100644 index 0000000..507fd97 --- /dev/null +++ b/src/async-worker.js @@ -0,0 +1,41 @@ +const { + Worker, isMainThread, parentPort, workerData +} = require('worker_threads'); + +const { SRT } = require('../build/Release/node_srt.node'); + +if (isMainThread) { + throw new Error("Worker module can not load on main thread"); +} + +(function run() { + const libSRT = new SRT(); + parentPort.on('message', (data) => { + if (!data.method) { + throw new Error('Worker message needs `method` property'); + } + /* + if (!data.workId) { + throw new Error('Worker message needs `workId` property'); + } + */ + let result = libSRT[data.method].apply(libSRT, data.args); + // TODO: see if we can do this using SharedArrayBuffer for example, + // or just leveraging Transferable objects capabilities ... ? + // FIXME: Performance ... ? + if (result instanceof Buffer) { + const buf = Buffer.allocUnsafe(result.length); + result.copy(buf); + result = buf; + } + parentPort.postMessage({ + // workId: data.workId, + timestamp: data.timestamp, + result + }); + }); +})(); + + + + diff --git a/src/async.js b/src/async.js new file mode 100644 index 0000000..4f9bce8 --- /dev/null +++ b/src/async.js @@ -0,0 +1,219 @@ +const { + Worker, isMainThread, parentPort, workerData +} = require('worker_threads'); + +const path = require('path'); + +const {performance} = require("perf_hooks"); + +const PROMISE_TIMEOUT_MS = 3000; + +/* +const WORK_ID_GEN_MOD = 0xFFF; +*/ + +class AsyncSRT { + + constructor() { + this._worker = new Worker(path.resolve(__dirname, './async-worker.js')); + this._worker.on('message', this._onWorkerMessage.bind(this)); + /* + this._workIdGen = 0; + this._workCbMap = new Map(); + */ + this._workCbQueue = []; + } + + _onWorkerMessage(data) { + const resolveTime = performance.now(); + const {timestamp, result, workId} = data; + + const callback = this._workCbQueue.shift(); + callback(result); + } + + _postAsyncWork(method, args, callback) { + const timestamp = performance.now(); + + // not really needed atm, + // only if the worker spawns async jobs itself internally + // and thus the queuing order of jobs would not be preserved + // across here and the worker side. + /* + if (this._workCbMap.size >= WORK_ID_GEN_MOD - 1) { + throw new Error('Can`t post more async work: Too many awaited callbacks unanswered in queue'); + } + const workId = this._workIdGen; + this._workIdGen = (this._workIdGen + 1) % WORK_ID_GEN_MOD; + this._workCbMap.set(workId, callback); + */ + + this._workCbQueue.push(callback); + this._worker.postMessage({method, args, /*workId,*/ timestamp}); + } + + /** + * + * @param {string} method + * @param {Array} args optional + * @param {Function} callback optional + */ + _createAsyncWorkPromise(method, args = [], callback = null, useTimeout = true) { + return new Promise((resolve, reject) => { + let timeout; + if (useTimeout) { + timeout = setTimeout(() => { + reject(new Error('Timeout exceeded while awaiting result from worker running native-addon module functions')); + }, PROMISE_TIMEOUT_MS); + } + const onResult = (result) => { + if (useTimeout) clearTimeout(timeout); + resolve(result); + if (callback) callback(result); // NOTE: the order doesn't matter for us, + // but intuitively the promise result should probably be resolved first. + }; + this._postAsyncWork(method, args, onResult); + }); + } + + /** + * + * @param {boolean} sender + * @returns SRTSOCKET identifier (integer value) or -1 (SRT_ERROR) + */ + createSocket(sender, callback) { + return this._createAsyncWorkPromise("createSocket", [sender], callback); + } + + /** + * + * @param socket + * @param address + * @param port + */ + bind(socket, address, port, callback) { + return this._createAsyncWorkPromise("bind", [socket, address, port], callback); + } + + /** + * + * @param socket + * @param backlog + */ + listen(socket, backlog, callback) { + return this._createAsyncWorkPromise("listen", [socket, backlog], callback); + } + + /** + * + * @param socket + * @param host + * @param port + */ + connect(socket, host, port, callback) { + return this._createAsyncWorkPromise("connect", [socket, host, port], callback); + } + + /** + * + * @param socket + * @returns File descriptor of incoming connection pipe + */ + accept(socket, callback) { + return this._createAsyncWorkPromise("accept", [socket], callback, false); + } + + /** + * + * @param socket + */ + close(socket, callback) { + return this._createAsyncWorkPromise("close", [socket], callback); + } + + /** + * + * @param socket + * @param chunkSize + * @returns {Promise} + */ + read(socket, chunkSize, callback) { + return this._createAsyncWorkPromise("read", [socket, chunkSize], callback); + } + + /** + * + * @param socket + * @param {Buffer} chunk + */ + write(socket, chunk, callback) { + // TODO: see if we can do this using SharedArrayBuffer for example, + // or just leveraging Transferable objects capabilities ... ? + // FIXME: Performance ... ? + const buf = Buffer.allocUnsafe(chunk.length); + chunk.copy(buf); + chunk = buf; + return this._createAsyncWorkPromise("write", [socket, chunk], callback); + } + + /** + * + * @param socket + * @param option + * @param value + */ + setSockOpt(socket, option, value, callback) { + return this._createAsyncWorkPromise("setSockOpt", [socket, option, value], callback); + } + + /** + * + * @param socket + * @param option + */ + getSockOpt(socket, option, callback) { + return this._createAsyncWorkPromise("getSockOpt", [socket, option], callback); + } + + /** + * + * @param socket + */ + getSockState(socket, callback) { + return this._createAsyncWorkPromise("getSockState", [socket], callback); + } + + /** + * @returns epid + */ + epollCreate(callback) { + return this._createAsyncWorkPromise("epollCreate", [], callback); + } + + /** + * + * @param epid + * @param socket + * @param events + */ + epollAddUsock(epid, socket, events, callback) { + return this._createAsyncWorkPromise("epollAddUsock", [epid, socket, events], callback); + } + + /** + * + * @param epid + * @param msTimeOut + */ + epollUWait(epid, msTimeOut, callback) { + return this._createAsyncWorkPromise("epollAddUsock", [epid, msTimeOut], callback); + } +} + +module.exports = {AsyncSRT}; + + + + + + From 8b1715c31d394478c410503dab8f98a5969d1f8a Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:14:29 +0200 Subject: [PATCH 05/16] add various examples for async API ("classic" callbacks / Promise / await) --- examples/async-srt-await.js | 25 +++++++++++++++++++++++++ examples/async-srt-promises.js | 32 ++++++++++++++++++++++++++++++++ examples/async-srt.js | 25 +++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 examples/async-srt-await.js create mode 100644 examples/async-srt-promises.js create mode 100644 examples/async-srt.js diff --git a/examples/async-srt-await.js b/examples/async-srt-await.js new file mode 100644 index 0000000..18de51c --- /dev/null +++ b/examples/async-srt-await.js @@ -0,0 +1,25 @@ +const { AsyncSRT } = require('../src/async.js'); + +const asyncSrt = new AsyncSRT(); + +(async function() { + const socket = await asyncSrt.createSocket(false); + console.log('createSocket() result:', socket); + let result = await asyncSrt.bind(socket, "0.0.0.0", 1234); + console.log('bind() result:', result); + result = await asyncSrt.listen(socket, 2); + console.log('listen() result:', result); + + awaitConnections(socket); + +})(); + +async function awaitConnections(socket) { + console.log('Awaiting incoming client connection ...'); + const fd = await asyncSrt.accept(socket); + console.log('New incoming client fd:', fd); +} + +setInterval(() => { + console.log('Doing other stuff in the meantime ... :)'); +}, 1000) diff --git a/examples/async-srt-promises.js b/examples/async-srt-promises.js new file mode 100644 index 0000000..62c820f --- /dev/null +++ b/examples/async-srt-promises.js @@ -0,0 +1,32 @@ +"use strict"; + +const { AsyncSRT } = require('../src/async.js'); + +const asyncSrt = new AsyncSRT(); + +let mySocket; + +asyncSrt.createSocket(false) + .catch((err) => console.error(err)) + .then((result) => { + console.log('createSocket:', result); + mySocket = result; + return result; + }) + .then((socket) => asyncSrt.bind(socket, "0.0.0.0", 1234)) + .then((result) => { + if (result !== 0) { + throw new Error('Failed bind'); + } + console.log('Bind success'); + return asyncSrt.listen(mySocket, 2); + }) + .then((result) => { + if (!result) { + console.log("Listen success"); + } else { + throw new Error('SRT listen error: ' + result); + } + }); + + diff --git a/examples/async-srt.js b/examples/async-srt.js new file mode 100644 index 0000000..9f794e7 --- /dev/null +++ b/examples/async-srt.js @@ -0,0 +1,25 @@ +"use strict"; + +const { AsyncSRT } = require('../src/async.js'); + +const asyncSrt = new AsyncSRT(); + +asyncSrt.createSocket(false, (result) => { + console.log('createSocket:', result); + const socket = result; + asyncSrt.bind(socket, "0.0.0.0", 1234, (result) => { + if (result !== 0) { + console.log('Failed bind'); + } else { + console.log('Bind success'); + asyncSrt.listen(socket, 2, (result) => { + if (!result) { + console.log("Listen success"); + } else { + console.log(result); + } + }); + } + }); +}); + From 977b0204a236349df041685a1b5658e97db8e95e Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:15:00 +0200 Subject: [PATCH 06/16] add .eslintignore (should go with commit where we just call "eslint .") --- .eslintignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..29b8616 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +build +deps +node_modules +tsc-lib From 95b8a81b35a74dba0ec8446835eb3116cbd9d8e5 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Tue, 28 Jul 2020 14:15:15 +0200 Subject: [PATCH 07/16] index.js: add missing semi --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d364e9c..c45dee1 100644 --- a/index.js +++ b/index.js @@ -7,4 +7,4 @@ module.exports = { Server: Server, SRTReadStream, SRTWriteStream -} \ No newline at end of file +}; \ No newline at end of file From 3d052fc8125a55f072793de565e5ff0c88b3771a Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Wed, 29 Jul 2020 23:17:01 +0200 Subject: [PATCH 08/16] async.js: fix method name litteral in epollUWait --- src/async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async.js b/src/async.js index 4f9bce8..b2ba32c 100644 --- a/src/async.js +++ b/src/async.js @@ -206,7 +206,7 @@ class AsyncSRT { * @param msTimeOut */ epollUWait(epid, msTimeOut, callback) { - return this._createAsyncWorkPromise("epollAddUsock", [epid, msTimeOut], callback); + return this._createAsyncWorkPromise("epollUWait", [epid, msTimeOut], callback); } } From 45cfdf943f581e92b248820486fc461398c01aa6 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Wed, 29 Jul 2020 23:39:31 +0200 Subject: [PATCH 09/16] async.js: allow for accept method to use a timeout opt (defaults to false), and a custom timeout value option (default to default timeout), which can potentially be set differently than the general default timeout. + make the timeout value a static class property so that it can be user-defined module-load wide. defaults to constant in module top scope. --- src/async.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/async.js b/src/async.js index b2ba32c..cc852e3 100644 --- a/src/async.js +++ b/src/async.js @@ -6,7 +6,7 @@ const path = require('path'); const {performance} = require("perf_hooks"); -const PROMISE_TIMEOUT_MS = 3000; +const DEFAULT_PROMISE_TIMEOUT_MS = 3000; /* const WORK_ID_GEN_MOD = 0xFFF; @@ -14,6 +14,12 @@ const WORK_ID_GEN_MOD = 0xFFF; class AsyncSRT { + /** + * @static + * @type {number} Promise-timeout in millis + */ + static TimeoutMs = DEFAULT_PROMISE_TIMEOUT_MS; + constructor() { this._worker = new Worker(path.resolve(__dirname, './async-worker.js')); this._worker.on('message', this._onWorkerMessage.bind(this)); @@ -119,8 +125,8 @@ class AsyncSRT { * @param socket * @returns File descriptor of incoming connection pipe */ - accept(socket, callback) { - return this._createAsyncWorkPromise("accept", [socket], callback, false); + accept(socket, callback, useTimeout = false, timeoutMs = AsyncSRT.TimeoutMs) { + return this._createAsyncWorkPromise("accept", [socket], callback, useTimeout, timeoutMs); } /** From 92e99f13f1df0bcd2382e6d288706e47f08dffbc Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Wed, 29 Jul 2020 23:53:17 +0200 Subject: [PATCH 10/16] async.js: fix for a rejected promise, make sure we don't resolve anymore + add a custom timeout value argument to _createAsyncWorkPromise --- src/async.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/async.js b/src/async.js index cc852e3..c115c3e 100644 --- a/src/async.js +++ b/src/async.js @@ -28,6 +28,7 @@ class AsyncSRT { this._workCbMap = new Map(); */ this._workCbQueue = []; + this._workCbListRejected = []; } _onWorkerMessage(data) { @@ -64,20 +65,28 @@ class AsyncSRT { * @param {Array} args optional * @param {Function} callback optional */ - _createAsyncWorkPromise(method, args = [], callback = null, useTimeout = true) { + _createAsyncWorkPromise(method, args = [], callback = null, useTimeout = true, timeoutMs = AsyncSRT.TimeoutMs) { return new Promise((resolve, reject) => { let timeout; - if (useTimeout) { - timeout = setTimeout(() => { - reject(new Error('Timeout exceeded while awaiting result from worker running native-addon module functions')); - }, PROMISE_TIMEOUT_MS); - } + let rejected = false; const onResult = (result) => { - if (useTimeout) clearTimeout(timeout); + // Q: signal somehow to app that timed-out call has had result after all? (only in case of using Promise..?) + if (rejected) { + // The reject thing only makes sense for Promise, + // and users can manage this aspect themselves when using plain callbacks. + if (callback) callback(result); + return; + } else if (useTimeout) clearTimeout(timeout); resolve(result); if (callback) callback(result); // NOTE: the order doesn't matter for us, // but intuitively the promise result should probably be resolved first. }; + if (useTimeout) { + timeout = setTimeout(() => { + reject(new Error('Timeout exceeded while awaiting result from worker running native-addon module functions')); + rejected = true; + }, timeoutMs); + } this._postAsyncWork(method, args, onResult); }); } From 435188be68482eb9ca6c6cbdc05452628042bdf4 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Wed, 29 Jul 2020 23:53:47 +0200 Subject: [PATCH 11/16] async.js: rm an experiment --- src/async.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/async.js b/src/async.js index c115c3e..73512e3 100644 --- a/src/async.js +++ b/src/async.js @@ -28,7 +28,6 @@ class AsyncSRT { this._workCbMap = new Map(); */ this._workCbQueue = []; - this._workCbListRejected = []; } _onWorkerMessage(data) { From 3762822ee8f2ff95bb9796ba0f5cb8a3fd3acc05 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Wed, 29 Jul 2020 23:54:16 +0200 Subject: [PATCH 12/16] fix a lint error in example --- examples/async-srt-await.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/async-srt-await.js b/examples/async-srt-await.js index 18de51c..4c381f3 100644 --- a/examples/async-srt-await.js +++ b/examples/async-srt-await.js @@ -22,4 +22,4 @@ async function awaitConnections(socket) { setInterval(() => { console.log('Doing other stuff in the meantime ... :)'); -}, 1000) +}, 1000); From 4006b8bf6dde69b5ca4e2232e06d4eef0ba71123 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Thu, 30 Jul 2020 01:43:56 +0200 Subject: [PATCH 13/16] add types for async api and fix some details on binding API types --- types/srt-api-async.d.ts | 107 +++++++++++++++++++++++++++++++++++++++ types/srt-api.d.ts | 14 ++--- 2 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 types/srt-api-async.d.ts diff --git a/types/srt-api-async.d.ts b/types/srt-api-async.d.ts new file mode 100644 index 0000000..1a02341 --- /dev/null +++ b/types/srt-api-async.d.ts @@ -0,0 +1,107 @@ +declare module "srt" { + + type AsyncSRTCallback = (result: T) => void; + + class AsyncSRT { + + static TimeoutMs: number; + + /** + * + * @param sender + * @returns SRTSOCKET identifier (integer value) + */ + createSocket(sender: boolean, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param address + * @param port + */ + bind(socket: number, address: string, port: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param backlog + */ + listen(socket: number, backlog: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param host + * @param port + */ + connect(socket: number, host: string, port: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @returns File descriptor of incoming connection pipe + */ + accept(socket: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + */ + close(socket: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param chunkSize + */ + read(socket: number, chunkSize: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param chunk + */ + write(socket: number, chunk: Buffer, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param option + * @param value + */ + setSockOpt(socket: number, option: SRTSockOpt, value: SRTSockOptValue, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + * @param option + */ + getSockOpt(socket: number, option: SRTSockOpt, callback?: AsyncSRTCallback): Promise + + /** + * + * @param socket + */ + getSockState(socket: number, callback?: AsyncSRTCallback): Promise + + /** + * @returns epid + */ + epollCreate(callback?: AsyncSRTCallback): Promise + + /** + * + * @param epid + * @param socket + * @param events + */ + epollAddUsock(epid: number, socket: number, events: number, callback?: AsyncSRTCallback): Promise + + /** + * + * @param epid + * @param msTimeOut + */ + epollUWait(epid: number, msTimeOut: number, callback?: AsyncSRTCallback): Promise + } +} diff --git a/types/srt-api.d.ts b/types/srt-api.d.ts index 0ee237a..84c36cd 100644 --- a/types/srt-api.d.ts +++ b/types/srt-api.d.ts @@ -48,7 +48,7 @@ declare module "srt" { * @param socket * @param chunkSize */ - read(socket: number, chunkSize: number): Buffer + read(socket: number, chunkSize: number): SRTReadReturn /** * @@ -63,14 +63,14 @@ declare module "srt" { * @param option * @param value */ - setSockOpt(socket: number, option: number, value: SRTSocketOptValue): number + setSockOpt(socket: number, option: SRTSockOpt, value: SRTSockOptValue): SRTResult /** * * @param socket * @param option */ - getSockOpt(socket: number, option: number): SRTSocketOptValue + getSockOpt(socket: number, option: SRTSockOpt): SRTSockOptValue /** * @@ -96,17 +96,19 @@ declare module "srt" { * @param epid * @param msTimeOut */ - epollUWait(epid: number, msTimeOut: number): SRTPollingEvent[] + epollUWait(epid: number, msTimeOut: number): SRTEpollEvent[] } - interface SRTPollingEvent { + interface SRTEpollEvent { socket: SRTFileDescriptor events: number } + type SRTReadReturn = Buffer | SRTResult.SRT_ERROR | null + type SRTFileDescriptor = number; - type SRTSocketOptValue = boolean | number | string + type SRTSockOptValue = boolean | number | string enum SRTResult { SRT_ERROR = -1, From 31abb6ada5d16e7f249997b708e491ea9e0fe147 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Thu, 30 Jul 2020 01:44:25 +0200 Subject: [PATCH 14/16] export async API to index --- index.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index c45dee1..167c971 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,12 @@ -const LIB = require('./build/Release/node_srt.node'); +const { SRT } = require('./build/Release/node_srt.node'); const Server = require('./src/server.js'); const { SRTReadStream, SRTWriteStream } = require('./src/stream.js'); +const { AsyncSRT } = require('./src/async'); module.exports = { - SRT: LIB.SRT, - Server: Server, + SRT, + Server, SRTReadStream, - SRTWriteStream -}; \ No newline at end of file + SRTWriteStream, + AsyncSRT, +}; From b96f2c53b2de1e393c56f827e41e7048ca3892c6 Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Thu, 30 Jul 2020 01:44:59 +0200 Subject: [PATCH 15/16] async.js: add some missing docs for private methods --- src/async.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/async.js b/src/async.js index 73512e3..404ce80 100644 --- a/src/async.js +++ b/src/async.js @@ -3,7 +3,6 @@ const { } = require('worker_threads'); const path = require('path'); - const {performance} = require("perf_hooks"); const DEFAULT_PROMISE_TIMEOUT_MS = 3000; @@ -30,6 +29,10 @@ class AsyncSRT { this._workCbQueue = []; } + /** + * @private + * @param {*} data + */ _onWorkerMessage(data) { const resolveTime = performance.now(); const {timestamp, result, workId} = data; @@ -38,6 +41,12 @@ class AsyncSRT { callback(result); } + /** + * @private + * @param {string} method + * @param {Array} args + * @param {Function} callback + */ _postAsyncWork(method, args, callback) { const timestamp = performance.now(); @@ -59,9 +68,9 @@ class AsyncSRT { } /** - * + * @private * @param {string} method - * @param {Array} args optional + * @param {Array} args optional * @param {Function} callback optional */ _createAsyncWorkPromise(method, args = [], callback = null, useTimeout = true, timeoutMs = AsyncSRT.TimeoutMs) { From fc6ce14c0ab1b013e2214b57244bfe3954f813db Mon Sep 17 00:00:00 2001 From: Stephan Hesse Date: Thu, 30 Jul 2020 01:45:18 +0200 Subject: [PATCH 16/16] include async types in index --- index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.d.ts b/index.d.ts index 086c608..d7a0064 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,5 +2,6 @@ /// /// /// +/// export * from "srt";