Example #1
0
  beforeEach(() => {
    const PROCESS_PATH = nuclideUri.join(
      __dirname,
      'fixtures/dummy-service/dummyioserver.py',
    );
    const OPTS = {
      cwd: nuclideUri.dirname(PROCESS_PATH),
      stdio: 'pipe',
      detached: false,
    };

    const serviceRegistry = new ServiceRegistry(
      [],
      [
        {
          name: 'dummy',
          definition: nuclideUri.join(
            __dirname,
            'fixtures/dummy-service/DummyService.js',
          ),
          implementation: nuclideUri.join(
            __dirname,
            'fixtures/dummy-service/DummyService.js',
          ),
          preserveFunctionNames: true,
        },
      ],
    );

    const processStream = spawn('python', [PROCESS_PATH], OPTS)
      // For the sake of our tests, simulate creating the process asynchronously.
      .subscribeOn(Scheduler.async);
    server = new RpcProcess('Dummy IO Server', serviceRegistry, processStream);
  });
Example #2
0
async function createHackProcess(
  fileCache: FileCache,
  configDir: string,
): Promise<HackProcess> {
  const command = await getHackCommand();
  if (command === '') {
    throw new Error("Couldn't find Hack command");
  }

  logger.info(`Creating new hack connection for ${configDir}: ${command}`);
  logger.info(`Current PATH: ${maybeToString(process.env.PATH)}`);
  try {
    await runCommand(command, ['start', configDir], {
      isExitError: ({exitCode}) =>
        !(exitCode === 0 || exitCode === HACK_SERVER_ALREADY_EXISTS_EXIT_CODE),
    }).toPromise();
  } catch (err) {
    if (err.exitCode != null) {
      throw new Error(
        `Hack server start failed with code: ${String(err.exitCode)}`,
      );
    }
    throw new Error(`Hack server failed with error: ${err.message}`);
  }
  const processStream = spawn(command, ['ide', configDir]);
  const hackProcess = new HackProcess(
    fileCache,
    `HackProcess-${configDir}`,
    processStream,
    configDir,
  );

  // If the process exits unexpectedly, create a new one immediately.
  const startTime = Date.now();
  hackProcess.observeExitMessage().subscribe(message => {
    // Dispose the process by removing it from the cache.
    if (processes.has(fileCache)) {
      processes.get(fileCache).delete(configDir);
    }
    if (
      message != null &&
      message.exitCode === HACK_IDE_NEW_CLIENT_CONNECTED_EXIT_CODE
    ) {
      logger.info('Not reconnecting Hack process--another client connected');
      return;
    }
    // If the process exited too quickly (possibly due to a crash), don't get
    // stuck in a loop creating and crashing it.
    const processUptimeMs = Date.now() - startTime;
    if (processUptimeMs < 1000) {
      logger.error('Hack process exited in <1s; not reconnecting');
      return;
    }
    logger.info(`Reconnecting with new HackProcess for ${configDir}`);
    processes.get(fileCache).get(configDir);
  });

  return hackProcess;
}
Example #3
0
function getOutputLines(command, args, opts) {
  return spawn(command, args, opts).switchMap(proc => {
    return getOutputStream(proc).reduce((acc, result) => {
      if (result.kind === 'stdout') {
        acc.push(result.data.trimRight());
      }
      return acc;
    }, []);
  });
}