type holyshared = Engineer<mixed>

PHP、Hack、Ruby、OCaml、Rust、Javascript周りの技術ブログ

Hackで書いたProcessパッケージ

Processパッケージをリファクタリングしました。
https://github.com/hhpack/process

主な変更点は下記の2点です。

  • stream_selectからstream_awaitへの置き換え
  • IDisposableを使用したリソース管理

stream_selectからstream_awaitへの置き換え

パイプの状態監視に今まではstream_selectを使用していました。
これをstream_awaitに置き換えました。

stream_awaitは非同期な関数なので、awaitを使用していたのですが、戻り値のステータスが期待した値を返してくれませんでした。

仕方ないので、\HH\Asio\join関数で処理を待つように変更したところ期待通り動作するようになりました。

stream_awaitは内部的にepollでも使ってるのかな?

before

await stream_await($handle, STREAM_AWAIT_READ, 0.2);

after

\HH\Asio\join(stream_await($handle, STREAM_AWAIT_READ, 0.2));

IDisposableを使用したリソース管理

前の実装までは__destructでプロセスのパイプをクローズしていたのですが、IDisposableが使えるようになったので、置き換えました。

これでブロックスコープを抜けた後などに、パイプをすぐにクローズできるようになりました。

この機能はHHVM3.24以降で利用可能です。 https://hhvm.com/blog/2018/01/16/hhvm-3.24.html

おそらく、C#ユーザーあたりから提案があったのだと思います。(async/awaitもそうだったはず)

<?hh //strict

use HHPack\Process;
use HHPack\Process\ProcessOptions;
use HHPack\Process\Output\{ Stdout, Stderr };

async function pipe_example() : Awaitable<void>
{
  $options = new ProcessOptions();
  $options->stdout(new Stdout());
  $options->stderr(new Stderr());

  using ($p = Process\spawn('hh_client restart', [], $options)) {
    await $p->wait();
  }

  using ($p = Process\spawn('hh_client check --json', [], $options)) {
    await $p->wait();
  }
}