worker_threads#Worker TypeScript Examples

The following examples show how to use worker_threads#Worker. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: auth-utils.ts    From relate with GNU General Public License v3.0 7 votes vote down vote up
authRedirectServer = (workerData: any): Promise<string> => {
    return new Promise((resolve, reject) => {
        const worker = new Worker(path.join(__dirname, 'auth-redirect-server.js'), {
            workerData,
        });

        worker.on('message', (data) => resolve(data));
        worker.on('error', reject);
        worker.on('exit', (exitCode) => {
            if (exitCode !== 0) {
                reject(new Error(`Worker stopped with exit code ${exitCode}`));
            }
        });
    });
}
Example #2
Source File: wrapWorkerFunc.ts    From joplin-utils with MIT License 6 votes vote down vote up
/**
 * 包装需要放到 worker 中执行的函数
 * 1. 当检查到当前文件不是 js 文件时会直接返回函数
 * 2. 当检查到在主线程时执行时,使用 Worker 包装并执行它
 * 3. 当检查到在 Worker 线程时,使用 expose 包装它然后执行
 * 注:目前是每次都创建新的 Worker,也许可以考虑支持复用 Worker
 * @param ep
 */
export function wrapWorkerFunc<T extends (...args: any[]) => any>(
  ep: T,
): Remote<T> {
  // return ep as Remote<T>
  if (path.extname(__filename) !== '.js') {
    return ep as Remote<T>
  }
  if (isMainThread) {
    return ((...args: any[]) => {
      const worker = new Worker(__filename)
      const fn = wrap<T>(nodeEndpoint(worker))
      return (fn(...args) as Promise<any>).finally(() => worker.unref())
    }) as Remote<T>
  }
  expose(ep, nodeEndpoint(parentPort!))
  return ep as Remote<T>
}
Example #3
Source File: h1emuserver.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
protected constructor(serverPort?: number) {
    super();
    this._serverPort = serverPort;
    this._protocol = new H1emuProtocol();
    this._connection = new Worker(
      `${__dirname}/../../shared/workers/udpServerWorker.js`,
      {
        workerData: { serverPort: serverPort },
      }
    );
  }
Example #4
Source File: soeserver.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
constructor(protocolName: string, serverPort: number, cryptoKey: Uint8Array) {
    super();
    Buffer.poolSize = 8192 * 4;
    this._protocolName = protocolName;
    this._serverPort = serverPort;
    this._cryptoKey = cryptoKey;
    this._maxMultiBufferSize = this._udpLength - 4 - this._crcLength;
    this._connection = new Worker(
      `${__dirname}/../shared/workers/udpServerWorker.js`,
      {
        workerData: { serverPort: serverPort },
      }
    );
    setInterval(() => {
      this.resetPacketsRate();
    }, 1000);
  }
Example #5
Source File: Worker.provider.ts    From nodetskeleton with MIT License 6 votes vote down vote up
async executeTask<ET>(task: WorkerTask): Promise<ET> {
    const agent = new Result();
    const taskResult = await new Promise((resolve, reject) => {
      const worker = new Worker(TaskDictionary[task.taskEnum], {
        workerData: { task: task },
      });
      worker.on("message", (data: ET | IWorkerError) => {
        if ((data as IWorkerError).statusCode) {
          agent.setError((data as IWorkerError).message, (data as IWorkerError).statusCode);
        }
        resolve(data as ET);
      });
      worker.on("error", (error) => {
        agent.setError(error.message, this.applicationStatusCode.WORKER_ERROR);
        reject(error);
      });
      worker.on("exit", (exitCode) => {
        console.log(`Worker in task ${task.taskEnum} exited with code ${exitCode}`);
      });
    });

    if (agent.error)
      throw new ApplicationError(WorkerProvider.name, agent.message, agent.statusCode);

    return Promise.resolve(taskResult as ET);
  }
Example #6
Source File: zoneserver.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
async start(): Promise<void> {
    debug("Starting server");
    debug(`Protocol used : ${this._protocol.protocolName}`);
    if (this._mongoAddress) {
      await this.connectMongo();
    }
    await this.setupServer();
    this._startTime += Date.now() + 82201232; // summer start
    this._startGameTime += Date.now();
    if (this._soloMode) {
      setupAppDataFolder();
    }
    if (this._dynamicWeatherEnabled) {
      this._dynamicWeatherWorker = new Worker(
        `${__dirname}/workers/dynamicWeather.js`,
        {
          workerData: {
            timeMultiplier: this._timeMultiplier,
            serverTime: this._serverTime,
            startTime: this._startTime,
          },
        }
      );
      this._dynamicWeatherWorker.on("message", (weather: Uint8Array) => {
        this.sendRawToAll(Buffer.from(weather));
      });
    }
    this._gatewayServer.start();
    this.worldRoutineTimer = setTimeout(
      () => this.worldRoutine.bind(this)(true),
      this.tickRate
    );
  }
Example #7
Source File: healthWorker.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
export function healthThreadDecorator(target: Target) {
  target.prototype._healthWorker = new Worker(`${__dirname}/healthWorker.js`, {
    workerData: { threadToWatchPid: process.pid },
  });
  if (!process.env.VSCODE_DEBUG) {
    target.prototype._healthWorker.on("message", () => {
      target.prototype._healthWorker.postMessage(true);
    });
  }
}
Example #8
Source File: parallel.ts    From backstage with Apache License 2.0 6 votes vote down vote up
/**
 * Spawns one or more worker threads using the `worker_threads` module.
 */
export async function runWorkerThreads<TResult, TData, TMessage>(
  options: WorkerThreadsOptions<TResult, TData, TMessage>,
): Promise<TResult[]> {
  const { worker, workerData, threadCount = 1, onMessage } = options;

  return Promise.all(
    Array(threadCount)
      .fill(0)
      .map(async () => {
        const thread = new Worker(`(${workerThread})(${worker})`, {
          eval: true,
          workerData,
        });

        return new Promise<TResult>((resolve, reject) => {
          thread.on('message', (message: WorkerThreadMessage) => {
            if (message.type === 'result') {
              resolve(message.result as TResult);
            } else if (message.type === 'error') {
              reject(message.error);
            } else if (message.type === 'message') {
              onMessage?.(message.message as TMessage);
            }
          });

          thread.on('error', reject);
          thread.on('exit', (code: number) => {
            reject(
              new Error(`Unexpected worker thread exit with code ${code}`),
            );
          });
        });
      }),
  );
}
Example #9
Source File: loginClientLoadTest.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
loginServer = new Worker(`${__dirname}/workers/loginServer.js`)
Example #10
Source File: PictureWorker.ts    From discord-qt with GNU General Public License v3.0 5 votes vote down vote up
/**
   * Worker that is being managed.
   */
  worker: Worker;
Example #11
Source File: PictureWorker.ts    From discord-qt with GNU General Public License v3.0 5 votes vote down vote up
constructor() {
    this.worker = new Worker(join(__dirname, 'worker.js'));
    this.worker.on('message', this.resolveImage.bind(this));
  }
Example #12
Source File: youtube.spawner.ts    From Discord-SimpleMusicBot with GNU General Public License v3.0 5 votes vote down vote up
worker = new Worker(path.join(__dirname, "./youtube.worker.js")).on("error", () => {})
Example #13
Source File: node-encrypt-worker.ts    From netmd-js with GNU General Public License v2.0 5 votes vote down vote up
// This generator uses a worker thread to encrypt the nextChunk
// while yielding the current one.
export function makeGetAsyncPacketIteratorOnWorkerThread(
    worker: Worker,
    progressCallback?: (progress: { totalBytes: number; encryptedBytes: number }) => void
) {
    return async function* getAsyncPacketIteratorOnWorkerThread({
        data,
        frameSize,
        kek,
        chunkSize,
    }: {
        data: ArrayBuffer;
        frameSize: number;
        kek: Uint8Array;
        chunkSize: number;
    }): AsyncIterableIterator<{ key: Uint8Array; iv: Uint8Array; data: Uint8Array }> {
        const w = worker;

        const initWorker = () => {
            w.postMessage(
                {
                    action: 'init',
                    data,
                    frameSize,
                    kek,
                    chunkSize,
                },
                [data]
            );
        };

        const askNextChunk = () => {
            w.postMessage({ action: 'getChunk' });
        };

        let resolver: (data: any) => void;
        w.on('message', msg => {
            resolver(msg);
        });

        let encryptedBytes = 0;
        let totalBytes = data.byteLength;
        let chunks: Promise<{ key: Uint8Array; iv: Uint8Array; data: Uint8Array } | null>[] = [];
        const queueNextChunk = () => {
            let chunkPromise = new Promise<{ key: Uint8Array; iv: Uint8Array; data: Uint8Array } | null>(resolve => {
                resolver = data => {
                    if (data !== null) {
                        encryptedBytes += data.byteLength;
                        progressCallback && progressCallback({ totalBytes, encryptedBytes });
                        queueNextChunk();
                    }
                    resolve(data);
                };
            });
            chunks.push(chunkPromise);
            askNextChunk();
        };

        initWorker();
        queueNextChunk();

        let i = 0;
        while (1) {
            let r = await chunks[i];
            delete chunks[i];
            if (r === null) {
                break;
            }
            yield r;
            i++;
        }
    };
}
Example #14
Source File: plugin_node_safe.ts    From omegga with ISC License 5 votes vote down vote up
#worker: Worker;
Example #15
Source File: plugin_node_safe.ts    From omegga with ISC License 5 votes vote down vote up
// create the worker for this plugin, attach emitter
  createWorker() {
    this.#worker = new Worker(
      path.join(__dirname, 'plugin_node_safe/worker.js'),
      {
        stdout: true,
        env: {
          VERBOSE: Logger.VERBOSE + '',
        },
      }
    );

    // pipe plugin output into omegga
    this.#outInterface = readline.createInterface({
      input: this.#worker.stdout,
      terminal: false,
    });
    this.#errInterface = readline.createInterface({
      input: this.#worker.stderr,
      terminal: false,
    });
    this.#outInterface.on('line', Logger.log);
    this.#errInterface.on('line', Logger.error);

    // attach message emitter
    this.#worker.on('message', ({ action, args }) =>
      this.plugin.emit(action, ...args)
    );

    // broadcast an error if there is one
    this.#worker.on('error', err => {
      Logger.error(
        '!>'.red,
        'error in plugin',
        this.getName().brightRed.underline,
        err
      );
    });

    // when the worker exits - set its variable to undefined this knows it's stopped
    this.#worker.on('exit', () => {
      this.omegga.off('*', this.eventPassthrough);
      this.#outInterface.removeAllListeners('line');
      this.#errInterface.removeAllListeners('line');
      try {
        if (this.#worker) this.#worker.terminate();
      } catch (err) {
        Logger.error(
          '!>'.red,
          'Error terminating worker for',
          this.getName().brightRed.underline,
          err
        );
      }
      this.#worker = undefined;
      this.emitStatus();
    });
  }
Example #16
Source File: plugin_node_safe.ts    From omegga with ISC License 5 votes vote down vote up
// require the plugin into the system, run the init func
  async load() {
    // can't load the plugin if it's already loaded
    if (typeof this.#worker !== 'undefined') return false;

    // vm restriction settings, default is access to everything
    const vmOptions = {
      builtin: this.access, // TODO: reference access file
      external: true, // TODO: reference access file
      isTypeScript: this.isTypeScript,
    };
    this.commands = [];

    try {
      const config = await this.storage.getConfig();
      if (this.pluginConfig?.emitConfig) {
        await fs.promises.writeFile(
          path.join(this.path, this.pluginConfig.emitConfig),
          JSON.stringify(config)
        );
      }
      this.createWorker();

      // tell the worker its name :)
      await this.emit('name', this.getName());

      // create the vm, export the plugin's class
      Logger.verbose('Loading safe plugin');
      if (!(await this.emit('load', this.path, vmOptions))[0]) throw '';

      // get some initial information to create an omegga proxy
      const initialData = bootstrap(this.omegga);
      // send all of the mock events to the proxy omegga
      Logger.verbose('Sending initial data to safe plugin');
      for (const ev in initialData) {
        try {
          (this.#worker as Worker).postMessage({
            action: 'brickadiaEvent',
            args: [ev, ...initialData[ev]],
          });
        } catch (e) {
          /* just writing 'safe' code :) */
        }
      }

      // pass events through
      this.omegga.on('*', this.eventPassthrough);
      Logger.verbose('Starting safe plugin');
      // actually start the plugin
      if (!(await this.emit('start', config))[0]) throw 'plugin failed start';

      this.emitStatus();
      return true;
    } catch (e) {
      // kill the worker
      await this.emit('kill');

      Logger.error(
        '!>'.red,
        'error loading node vm plugin',
        this.getName().brightRed.underline,
        e
      );
      this.emitStatus();
      return false;
    }
  }
Example #17
Source File: parallel.ts    From backstage with Apache License 2.0 5 votes vote down vote up
/**
 * Spawns one or more worker threads using the `worker_threads` module.
 * Each thread processes one item at a time from the provided `options.items`.
 */
export async function runWorkerQueueThreads<TItem, TResult, TData>(
  options: WorkerQueueThreadsOptions<TItem, TResult, TData>,
): Promise<TResult[]> {
  const items = Array.from(options.items);
  const {
    workerFactory,
    workerData,
    threadCount = Math.min(getEnvironmentParallelism(), items.length),
  } = options;

  const iterator = items[Symbol.iterator]();
  const results = new Array<TResult>();
  let itemIndex = 0;

  await Promise.all(
    Array(threadCount)
      .fill(0)
      .map(async () => {
        const thread = new Worker(`(${workerQueueThread})(${workerFactory})`, {
          eval: true,
          workerData,
        });

        return new Promise<void>((resolve, reject) => {
          thread.on('message', (message: WorkerThreadMessage) => {
            if (message.type === 'start' || message.type === 'result') {
              if (message.type === 'result') {
                results[message.index] = message.result as TResult;
              }
              const { value, done } = iterator.next();
              if (done) {
                thread.postMessage({ type: 'done' });
              } else {
                thread.postMessage({
                  type: 'item',
                  index: itemIndex,
                  item: value,
                });
                itemIndex += 1;
              }
            } else if (message.type === 'error') {
              const error = new Error(message.error.message);
              error.name = message.error.name;
              error.stack = message.error.stack;
              reject(error);
            }
          });

          thread.on('error', reject);
          thread.on('exit', (code: number) => {
            if (code !== 0) {
              reject(new Error(`Worker thread exited with code ${code}`));
            } else {
              resolve();
            }
          });
        });
      }),
  );

  return results;
}
Example #18
Source File: create-data-service.ts    From amplication with Apache License 2.0 5 votes vote down vote up
export async function createDataService(
  entities: Entity[],
  roles: Role[],
  appInfo: AppInfo,
  logger: winston.Logger = defaultLogger,
  useWorker = true
): Promise<Module[]> {
  if (useWorker) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(
        path.resolve(__dirname, "./create-data-service-worker.js")
      );

      worker.on("error", reject);
      worker.on("exit", (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
      worker.on("message", (data: WorkerResult) => {
        if (data.message) {
          logger.info(data.message);
        }
        if (data.error) {
          reject(data.error);
        }
        if (data.done && data.modules) {
          resolve(data.modules);
        }
      });
      worker.postMessage({
        entities,
        roles,
        appInfo,
      });
    });
  } else {
    console.warn(
      "Creating data service without a worker. It is recommended to always use useWorker=true "
    );
    return await createDataServiceImpl(entities, roles, appInfo, logger);
  }
}
Example #19
Source File: soeserver.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
private _connection: Worker;
Example #20
Source File: loginserver.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
_httpServer!: Worker;
Example #21
Source File: loginserver.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
async start(): Promise<void> {
    debug("Starting server");
    if (this._mongoAddress) {
      const mongoClient = (this._mongoClient = new MongoClient(
        this._mongoAddress,
        { maxPoolSize: 100 }
      ));
      try {
        await mongoClient.connect();
      } catch (e) {
        throw debug(
          "[ERROR]Unable to connect to mongo server " + this._mongoAddress
        );
      }
      debug("connected to mongo !");
      // if no collections exist on h1server database , fill it with samples
      const dbIsEmpty =
        (await mongoClient.db("h1server").collections()).length < 1;
      if (dbIsEmpty) {
        await initMongo(mongoClient, debugName);
      }
      this._db = mongoClient.db("h1server");
      this._zoneWhitelist = await this._db
        .collection("zone-whitelist")
        .find({})
        .toArray();

      setInterval(async () => {
        this._zoneWhitelist = await this._db
          .collection("zone-whitelist")
          .find({})
          .toArray();
      }, 60000);
    }

    if (this._soloMode) {
      setupAppDataFolder();
    }
    this._soeServer.start(this._crcLength, this._udpLength);
    if (this._mongoAddress && this._enableHttpServer) {
      this._httpServer = new Worker(`${__dirname}/workers/httpServer.js`, {
        workerData: {
          MONGO_URL: this._mongoAddress,
          SERVER_PORT: this._httpServerPort,
        },
      });
      this._httpServer.on("message", (message: httpServerMessage) => {
        const { type, requestId, data } = message;
        switch (type) {
          case "pingzone": {
            const response: httpServerMessage = {
              type: "pingzone",
              requestId: requestId,
              data: Object.values(this._zoneConnections).includes(data)
                ? "pong"
                : "error",
            };
            this._httpServer.postMessage(response);
            break;
          }
          case "ping": {
            const response: httpServerMessage = {
              type: "ping",
              requestId: requestId,
              data: "pong",
            };
            this._httpServer.postMessage(response);
            break;
          }
          default:
            break;
        }
      });
    }
  }
Example #22
Source File: h1emuserver.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
_connection: Worker;
Example #23
Source File: zoneClientLoadTest.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
ZoneServer = new Worker(`${__dirname}/workers/zoneServer.js`)
Example #24
Source File: monitor-client.ts    From Cromwell with MIT License 5 votes vote down vote up
worker = new Worker(monitorPath)
Example #25
Source File: cli.ts    From netmd-js with GNU General Public License v2.0 4 votes vote down vote up
async function main() {
    async function openDeviceOrExit(usb: USB) {
        let netmdInterface = await openNewDevice(usb);
        if (netmdInterface === null) {
            printNotDeviceFound();
            process.exit(1);
        }
        return netmdInterface;
    }

    const args = yargs
        .command(
            'devices',
            'list devices',
            yargs => {},
            async argv => {
                let device = await listDevice(usb);
                printDevice(device);
            }
        )
        .command(
            'status [readIntervalMS]',
            'show device status',
            yargs => {
                return yargs.option('readIntervalMS', {
                    alias: 'i',
                    default: 0,
                    type: 'number',
                });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                if (argv.readIntervalMS > 0) {
                    console.log('press Q to exit. Look at cli.js for other commands\n');
                    readline.emitKeypressEvents(process.stdin);
                    process.stdin.setRawMode(true);
                    process.stdin.on('keypress', async (str, key) => {
                        try {
                            switch (key.name) {
                                case 'q':
                                    process.exit(0);
                                    break;
                                case 'right':
                                    await netmdInterface.nextTrack();
                                    break;
                                case 'left':
                                    await netmdInterface.previousTrack();
                                    break;
                                case 'up':
                                    await netmdInterface.fast_forward();
                                    break;
                                case 'down':
                                    await netmdInterface.rewind();
                                    break;
                                case 'space':
                                    await netmdInterface.play();
                                    break;
                                case 'return':
                                    await netmdInterface.stop();
                                    break;
                                default:
                                    break;
                            }
                        } catch (e) {
                            console.log('Failed', e.stack);
                        }
                    });
                }

                do {
                    const status = await getDeviceStatus(netmdInterface);
                    console.log(status);
                    await sleep(argv.readIntervalMS);
                } while (argv.readIntervalMS > 0);
            }
        )
        .command(
            'command [command]',
            'send command to device',
            yargs => {
                return yargs.positional('command', {
                    alias: 'c',
                    choices: ['play', 'stop', 'next', 'prev', 'eject'],
                });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                const command = argv.command;
                switch (command) {
                    case 'play':
                        await netmdInterface.play();
                        break;
                    case 'stop':
                        await netmdInterface.stop();
                        break;
                    case 'next':
                        await netmdInterface.nextTrack();
                        break;
                    case 'prev':
                        await netmdInterface.previousTrack();
                        break;
                    case 'eject':
                        await netmdInterface.ejectDisc();
                        break;
                    default:
                        throw new Error(`Unexpected command ${command}`);
                }
            }
        )
        .command(
            'goto [track]',
            'go to specific track',
            yargs => {
                return yargs.positional('track', {
                    alias: 't',
                    type: 'number',
                    demandOption: true,
                });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                await netmdInterface.gotoTrack(argv.track);
            }
        )
        .command(
            'll [command]',
            'send low level command to device',
            yargs => {
                return yargs.positional('command', {
                    type: 'string',
                    alias: 'c',
                    demandOption: true,
                });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                console.log(await netmdInterface.sendQuery(formatQuery(argv.command as string)));
            }
        )
        .command(
            'wipe',
            'erase the disc',
            yargs => {},
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                await netmdInterface.eraseDisc();
            }
        )
        .command(
            'ls',
            'list device content',
            yargs => {},
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                let content = await listContent(netmdInterface);
                printDisc(content);
            }
        )
        .command(
            'set_raw_title [raw_title]',
            'set disc title and group info',
            yargs => {
                return yargs
                    .option('full_width', {
                        alias: 'w',
                        describe: 'Use the full width slot (Hiragana/Katakana/Kanji)',
                        default: false,
                        demandOption: false,
                        type: 'boolean',
                    })
                    .positional('raw_title', {
                        describe: 'new raw_title to set',
                        type: 'string',
                    })
                    .demandOption(['raw_title']);
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                await netmdInterface.setDiscTitle(argv.raw_title, argv.full_width);
            }
        )
        .command(
            'upload [inputfile]',
            'upload music to your device',
            yargs => {
                return yargs
                    .positional('inputfile', {
                        describe: 'music file to upload',
                        type: 'string',
                    })
                    .option('format', {
                        alias: 'f',
                        default: 'sp',
                        choices: ['sp', 'lp2', 'lp105', 'lp4'],
                    })
                    .option('title', {
                        alias: 't',
                        type: 'string',
                    })
                    .demandOption(['inputfile']);
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);

                const stringToWirefromat: { [k: string]: Wireformat } = {
                    sp: Wireformat.pcm,
                    lp2: Wireformat.lp2,
                    lp105: Wireformat.l105kbps,
                    lp4: Wireformat.lp4,
                };

                const progressCallback = (progress: { writtenBytes: number; totalBytes: number }) => {
                    const { writtenBytes, totalBytes } = progress;
                    console.log(`Transferred bytes ${writtenBytes} of ${totalBytes}`, ~~((writtenBytes / totalBytes) * 100) + '%');
                };

                const data = fs.readFileSync(argv.inputfile);
                const format = stringToWirefromat[argv.format];
                const title = argv.title || sanitizeTrackTitle(argv.inputfile);

                const getAsyncPacketIteratorOnWorkerThread = makeGetAsyncPacketIteratorOnWorkerThread(
                    new Worker(path.join(__dirname, 'node-encrypt-worker.js'))
                );
                let mdTrack = new MDTrack(title, format, data.buffer, 0x100000 /* ~1Mb */, '', getAsyncPacketIteratorOnWorkerThread);

                let start = Date.now();
                await download(netmdInterface, mdTrack, progressCallback);
                let stop = Date.now();
                console.log('Time:', stop - start);
            }
        )
        .command(
            'download [track_number] [outputfile]',
            'download song from player to the PC. Track indexes start from 0. Only applicable to MZ-RH1 / MZ-M200',
            yargs => {
                return yargs
                    .positional('track_number', {
                        describe: 'track index',
                        type: 'number',
                        demandOption: true,
                    })
                    .positional('outputfile', {
                        describe: 'output file',
                        type: 'string',
                        demandOption: false,
                    });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);

                const [format, data] = await upload(netmdInterface, argv.track_number, ({ readBytes, totalBytes }) => {
                    console.log(`Reading ${readBytes} / ${totalBytes}`);
                });

                const outfile =
                    argv.outputfile ||
                    `${await netmdInterface.getTrackTitle(argv.track_number)}.${
                        [DiscFormat.lp2, DiscFormat.lp4].includes(format) ? 'wav' : 'aea'
                    }`;

                fs.writeFileSync(outfile, data);
            }
        )
        .command(
            'rename [track_number] [title]',
            'set track title. Track indexes start from 0',
            yargs => {
                return yargs
                    .positional('title', {
                        describe: 'new title for track',
                        type: 'string',
                        demandOption: true,
                    })
                    .positional('track_number', {
                        describe: 'track index',
                        type: 'number',
                        demandOption: true,
                    })
                    .option('full_width', {
                        alias: 'w',
                        describe: 'Use the full width slot (Hiragana/Katakana/Kanji)',
                        default: false,
                        demandOption: false,
                        type: 'boolean',
                    });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                await netmdInterface.setTrackTitle(argv.track_number, argv.title, argv.full_width);
            }
        )
        .command(
            'move [src_track_number] [dst_track_number]',
            'move track. Track indexes start from 0',
            yargs => {
                return yargs
                    .positional('src_track_number', {
                        describe: 'Source track number',
                        type: 'number',
                        demandOption: true,
                    })
                    .positional('dst_track_number', {
                        describe: 'Destination track number',
                        type: 'number',
                        demandOption: true,
                    });
            },
            async argv => {
                let netmdInterface = await openDeviceOrExit(usb);
                await netmdInterface.moveTrack(argv.src_track_number, argv.dst_track_number);
            }
        )
        .option('verbose', {
            alias: 'v',
            type: 'boolean',
            description: 'Run with verbose logging',
        })
        .demandCommand().argv;
}
Example #26
Source File: saved-model.worker.ts    From node-question-answering with Apache License 2.0 4 votes vote down vote up
export class SavedModelWorker extends Worker {
  private inferencePort: MessagePort;
  private initPort: MessagePort;
  private loaded?: true;
  private loadPort: MessagePort;
  private models = new Map<string, ModelInfos>();
  private queues = new Map<string, InferenceTask[]>();
  private taskId = 0;

  constructor() {
    super(joinPaths(__filename, "../saved-model.worker-thread.js"), {
      env: SHARE_ENV
    });

    const initChannel = new MessageChannel();
    this.initPort = initChannel.port2;

    const loadChannel = new MessageChannel();
    this.loadPort = loadChannel.port2;

    const inferenceChannel = new MessageChannel();
    this.inferencePort = inferenceChannel.port2;
    this.inferencePort.setMaxListeners(1000000);

    this.once("online", () => {
      this.initPort.once("close", () => (this.loaded = true));
      const message: InitMessage = {
        type: "init",
        initPort: initChannel.port1,
        loadPort: loadChannel.port1,
        inferencePort: inferenceChannel.port1
      };

      this.postMessage(message, [
        initChannel.port1,
        loadChannel.port1,
        inferenceChannel.port1
      ]);
    });

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    this.loadPort.on("message", (data: { model: string; error?: any }) => {
      const modelInfos = this.models.get(data.model);
      if (data.error) {
        modelInfos?.onloaderror?.(data.error);
        return;
      }

      modelInfos?.onloaded?.();
      this.models.set(data.model, { loaded: true });
      this.run(data.model);
    });
  }

  loadModel(params: FullParams): Promise<void> {
    return new Promise<void>((resolve, reject) => {
      this.models.set(params.path, {
        loaded: false,
        onloaded: resolve,
        onloaderror: reject
      });

      this.queues.set(params.path, []);

      if (this.loaded) {
        this.postMessage({ type: "load", params });
      } else {
        this.initPort.once("close", () => {
          this.postMessage({ type: "load", params });
        });
      }
    });
  }

  queueInference(
    modelPath: string,
    ids: number[][],
    attentionMask: number[][],
    tokenTypeIds?: number[][]
  ): Promise<[Logits, Logits]> {
    const taskId = this.taskId++;
    return new Promise<[Logits, Logits]>((resolve, reject) => {
      const inferenceTask: InferenceTask = {
        id: taskId,
        model: modelPath,
        onsuccess: resolve,
        onerror: reject,
        inputs: { ids, attentionMask, tokenTypeIds }
      };

      const model = this.models.get(inferenceTask.model);
      if (!model?.loaded) {
        const queue = this.queues.get(inferenceTask.model);
        queue && queue.push(inferenceTask);
      } else {
        this.runTask(inferenceTask);
      }
    });
  }

  private run(model: string): void {
    const queue = this.queues.get(model) ?? [];
    const queueLength = queue.length;
    for (let i = 0; i < queueLength; i++) {
      this.runTask(queue[i]);
    }

    queue.splice(0, queueLength);
  }

  private runTask(task: InferenceTask): void {
    const listener = (data: {
      _id: number;
      logits: [Logits, Logits];
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      error?: any;
    }): void => {
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      if (data._id != task!.id) {
        return;
      } else {
        this.inferencePort.removeListener("message", listener);
      }

      if (data.logits) {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        task!.onsuccess(data.logits);
      } else {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        task!.onerror(data.error);
      }
    };

    this.inferencePort.on("message", listener);
    const message: InferenceMessage = {
      _id: task.id,
      type: "infer",
      inputs: task.inputs,
      model: task.model
    };

    this.postMessage(message);
  }
}
Example #27
Source File: karma-test-explorer-reporter.ts    From karma-test-explorer with MIT License 4 votes vote down vote up
export function KarmaTestExplorerReporter(
  this: any,
  baseReporterDecorator: any,
  emitter: EventEmitter,
  karmaLogger: any,
  injector: any
) {
  baseReporterDecorator(this);

  // --- Setup logger ---

  const logLevel = process.env[KarmaEnvironmentVariable.KarmaReporterLogLevel] as LogLevel;

  const logger: Logger = LoggerAdapter.fromBasicLog(
    karmaLogger.create(`reporter:${KarmaTestExplorerReporter.name}`),
    logLevel,
    { bypassUnderlyingTraceMethod: true }
  );

  // --- Setup worker to communicate with extension ---

  const socketPort = Number.parseInt(process.env[KarmaEnvironmentVariable.KarmaSocketPort]!, 10);

  const workerData: TestResultEmitterWorkerData = {
    socketPort,
    pingTimeout: KARMA_SOCKET_PING_TIMEOUT,
    pingInterval: KARMA_SOCKET_PING_INTERVAL
  };

  const workerScriptFile = resolve(__dirname, './test-result-emitter-worker.js');
  const worker = new Worker(workerScriptFile, { workerData });

  logger.debug(
    () => `Using socket port from '${KarmaEnvironmentVariable.KarmaSocketPort}' env variable: ${socketPort}`
  );

  logger.debug(
    () => `Using ping timeout of '${KARMA_SOCKET_PING_TIMEOUT}' and ping interval of '${KARMA_SOCKET_PING_INTERVAL}'`
  );

  configureTimeouts(injector);

  const sendEvent = (event: KarmaEvent) => {
    worker.postMessage({ ...event });
  };

  // --- Setup karma event listeners ---

  const karmaEventHandler: MultiEventHandler<KarmaEventName, (eventName: KarmaEventName, ...args: any[]) => void> =
    new MultiEventHandler(logger);

  karmaEventHandler.setDefaultHandler((eventName: string, ...args: any[]) => {
    logger.debug(() => `No specific handler for event: ${eventName}`);
    const isErrorEvent = eventName.toLowerCase().includes('error');

    if (isErrorEvent) {
      logger.trace(
        () =>
          `No specific handler for received error event '${eventName}' with data: ` +
          `${JSON.stringify(args, getCircularReferenceReplacer(), 2)}`
      );
    }
    sendEvent({ name: eventName as KarmaEventName });
  });

  karmaEventHandler.setErrorHandler((eventName: string, error: Error, ...args: any[]) => {
    logger.error(() => `Error while handling event '${eventName}': ${error}`);
    logger.trace(
      () =>
        `Event data for errored '${eventName}' event handling: ` +
        `${JSON.stringify(args, getCircularReferenceReplacer(), 2)}`
    );
  });

  interceptAllEmitterEvents(emitter, (eventName: string, ...args: any[]) => {
    logger.trace(() => `New Karma event: ${JSON.stringify({ eventName, args }, getCircularReferenceReplacer(), 2)}`);
    karmaEventHandler.handleEvent(eventName as KarmaEventName, eventName as KarmaEventName, ...args);
  });

  karmaEventHandler.setEventHandler(KarmaEventName.Listening, (name: KarmaEventName, port: number) => {
    sendEvent({ name, port });
  });

  karmaEventHandler.setEventHandler(KarmaEventName.RunStart, (name: KarmaEventName, browsers: any) => {
    const clientArgs: string[] = browsers?.emitter?._injector?._providers?.config?.[1]?.client?.args ?? [];
    let runId: string | undefined;

    logger.debug(() => `Karma event '${name}' has client args: ${JSON.stringify(clientArgs, null, 2)}`);

    if (clientArgs) {
      const runIdArg = clientArgs.find(clientArg => clientArg.startsWith(KARMA_TEST_RUN_ID_FLAG));

      if (runIdArg) {
        runId = runIdArg.split('=')[1];
        logger.debug(() => `Karma event '${name}' has runId: ${runId}`);
      }
    }

    sendEvent({
      name,
      runId,
      browsers: browsers.map(getBrowserInfo)
    });
  });

  karmaEventHandler.setEventHandler(KarmaEventName.BrowserStart, (name: KarmaEventName, browser: any, info: any) => {
    logger.trace(() => `Karma event '${name}' has 'info': ${JSON.stringify(info, getCircularReferenceReplacer(), 2)}`);

    sendEvent({
      name,
      browser: getBrowserInfo(browser)
    });
  });

  karmaEventHandler.setEventHandler(
    KarmaEventName.SpecComplete,
    (name: KarmaEventName, browser: any, spec: Record<string, any>) => {
      const status: TestStatus = spec.skipped
        ? TestStatus.Skipped
        : spec.success
        ? TestStatus.Success
        : TestStatus.Failed;

      const specResult: LightSpecCompleteResponse = {
        id: spec.id,
        failureMessages: spec.log,
        suite: spec.suite,
        description: spec.description,
        status,
        timeSpentInMilliseconds: spec.time
      };

      sendEvent({
        name,
        browser: getBrowserInfo(browser),
        results: specResult
      });
    }
  );

  karmaEventHandler.setEventHandler(
    KarmaEventName.BrowserComplete,
    (name: KarmaEventName, browser: any, runInfo: any) => {
      logger.trace(
        () => `Karma event '${name}' has 'runInfo': ${JSON.stringify(runInfo, getCircularReferenceReplacer(), 2)}`
      );

      sendEvent({
        name,
        browser: getBrowserInfo(browser)
      });
    }
  );

  karmaEventHandler.setEventHandler(
    KarmaEventName.RunComplete,
    (name: KarmaEventName, browsers: any, runResult: KarmaTestResults) => {
      const clientArgs: string[] = browsers?.emitter?._injector?._providers?.config?.[1]?.client?.args ?? [];
      let runId: string | undefined;

      logger.debug(() => `Karma event '${name}' has client args: ${JSON.stringify(clientArgs, null, 2)}`);

      if (clientArgs) {
        const runIdArg = clientArgs.find(clientArg => clientArg.startsWith(KARMA_TEST_RUN_ID_FLAG));

        if (runIdArg) {
          runId = runIdArg.split('=')[1];
          logger.debug(() => `Karma event '${name}' has runId: ${runId}`);
        }
      }

      const runStatus = runResult.disconnected
        ? TestRunStatus.Timeout
        : runResult.error
        ? TestRunStatus.Error
        : TestRunStatus.Complete;

      sendEvent({
        name,
        runId,
        runStatus,
        exitCode: runResult.exitCode,
        browsers: browsers.map(getBrowserInfo),
        error: typeof runResult.error === 'string' ? runResult.error : undefined
      });
    }
  );

  karmaEventHandler.setEventHandler(KarmaEventName.BrowserError, (name: KarmaEventName, browser: any, error: any) => {
    sendEvent({
      name,
      browser: getBrowserInfo(browser),
      error
    });
  });

  karmaEventHandler.setEventHandler(KarmaEventName.BrowserProcessFailure, (name: KarmaEventName, failureData: any) =>
    sendEvent({
      name,
      error: failureData.error
    })
  );

  karmaEventHandler.setEventHandler(KarmaEventName.BrowsersReady, (name: KarmaEventName) => {
    sendEvent({ name });
  });

  karmaEventHandler.setEventHandler(KarmaEventName.BrowsersChange, (name: KarmaEventName, browsers: any) => {
    sendEvent({
      name,
      browsers: browsers.map(getBrowserInfo)
    });
  });
}
Example #28
Source File: boot_server.ts    From serum-vial with Mozilla Public License 2.0 4 votes vote down vote up
export async function bootServer({
  port,
  nodeEndpoint,
  wsEndpointPort,
  minionsCount,
  markets,
  commitment,
  bootDelay
}: BootOptions) {
  // multi core support is linux only feature which allows multiple threads to bind to the same port
  // see https://github.com/uNetworking/uWebSockets.js/issues/304 and https://lwn.net/Articles/542629/
  const MINIONS_COUNT = os.platform() === 'linux' ? minionsCount : 1
  let readyMinionsCount = 0

  logger.log(
    'info',
    MINIONS_COUNT === 1 ? 'Starting single minion worker...' : `Starting ${MINIONS_COUNT} minion workers...`
  )
  minionReadyChannel.onmessage = () => readyMinionsCount++

  // start minions workers and wait until all are ready

  for (let i = 0; i < MINIONS_COUNT; i++) {
    const minionWorker = new Worker(path.resolve(__dirname, 'minion.js'), {
      workerData: { nodeEndpoint, port, markets, minionNumber: i }
    })

    minionWorker.on('error', (err) => {
      logger.log('error', `Minion worker ${minionWorker.threadId} error occurred: ${err.message} ${err.stack}`)
      throw err
    })
    minionWorker.on('exit', (code) => {
      logger.log('error', `Minion worker: ${minionWorker.threadId} died with code: ${code}`)
    })
  }

  await new Promise<void>(async (resolve) => {
    while (true) {
      if (readyMinionsCount === MINIONS_COUNT) {
        break
      }
      await wait(100)
    }

    resolve()
  })

  logger.log('info', `Starting serum producers for ${markets.length} markets, rpc endpoint: ${nodeEndpoint}`)

  let readyProducersCount = 0

  serumProducerReadyChannel.onmessage = () => readyProducersCount++

  for (const market of markets) {
    const serumProducerWorker = new Worker(path.resolve(__dirname, 'serum_producer.js'), {
      workerData: { market, nodeEndpoint, commitment, wsEndpointPort }
    })

    serumProducerWorker.on('error', (err) => {
      logger.log(
        'error',
        `Serum producer worker ${serumProducerWorker.threadId} error occurred: ${err.message} ${err.stack}`
      )
      throw err
    })

    serumProducerWorker.on('exit', (code) => {
      logger.log('error', `Serum producer worker: ${serumProducerWorker.threadId} died with code: ${code}`)
    })

    // just in case to not get hit by serum RPC node rate limits...
    await wait(bootDelay)
  }

  await new Promise<void>(async (resolve) => {
    while (true) {
      if (readyProducersCount === markets.length) {
        break
      }
      await wait(100)
    }

    resolve()
  })
}