speedygosh

[トップ][一覧][最近の更新]


概要

nailgun / speedycgi / perperlの、Gauche版のようなもの。

要は、各種CGIやscmailのような、「たまにしか実行されない時もあるが、嵐のように激しく連続で実行される時もある」スクリプトを、それなりに高速に動作させる為のツール。

goshの起動オーバーヘッドがperl等と比較するとどうにも結構大きいので、負荷を抑える目的で作成しました。

初回実行時は起動速度は変化しませんが、その際に内部で勝手にバックエンド起動を行い、二回目以降の実行は高速起動されます。一定時間(デフォルト設定では90秒)の間実行されないとバックエンドは自動終了します。

Cで書かれたESTPクライアント部(speedygoshコマンド)と、Gaucheで書かれたESTPサーバ部(speedy_backend相当、つまり常駐プロセス。実体はspeedygosh.server-estpモジュール)の二つによって構成されます。

補足

以前は「speedycgiのGauche用clone」と説明していましたが、これだと語弊があるので説明文を直しました。

「speedycgiのgosh版が欲しい」と思って作ったので、unix domain socketを使うアイデアや利用場面は同じです。 が、基本的には全部自前で書いてますし(sha.cとか除いて)、内部構造はかなり違います(良くも悪くも)。

元々は、speedygoshは、ESTPestpdを作る最中に完成した副産物でした。

必要要件

ライセンス

修正BSD風ライセンスです。 tarball同梱のCOPYINGに詳細(といっても、定型文のみですが)が書いてあります。

尚、同梱のsha.c, sha.hは、Gaucheからもらってきました(public domainと書いてありました)。

ダウンロード

パッケージ

リポジトリ(移動しました)

ChangeLog

インストール

gauche-package installに対応しました。

gauche-package install speedygosh-x.y.z.tgz

これで、Gaucheにspeedygoshモジュールがインストールされ、goshがインストールされているディレクトリにspeedygoshコマンドが生成されます。

使い方

基本的には、スクリプトの一行目の「#!/path/to/gosh」を「#!/path/to/speedygosh」に変更するだけです。

但し、speedygoshには、後述の、通常のgoshにはない様々な制約があります。 この制約のどれかに引っかかる場合は使わない方がいいでしょう。

「#!/path/to/speedygosh」行に引数を付ける事で、動作に関する設定を行う事ができます(※osによっては、引数を一つしかつけられないものもあるそうです。注意!)。 具体的には、以下の通りになります。

引数

以下の引数が設定可能です。

shebang行での引数指定時の重要な制約(仕様)

speedygoshモジュール

speedygoshプロセスの挙動を操作する為に、いくつかの手続きが提供されます。

(use speedygosh)

によって、それらの手続きをimportする事ができます。

on-speedygosh?

(on-speedygosh?)

speedygosh-safety-shutdown

(speedygosh-safety-shutdown)

speedygosh-add-termination-handler!

(speedygosh-add-termination-handler! thunk)

speedygosh-delete-termination-handler!

(speedygosh-delete-termination-handler! thunk)

この他にも、動的にspeedygoshの設定の一部を変更できるような手続きが今後、提供される可能性があります。

自作自演faq

仕様上の制約

一時ファイル

stderrに対する不完全性

シグナルに対する不完全性

起動関連

スクリプト関連

その他

動作概要

動作の流れ

クライアント(speedygoshコマンド)サイド

  1. クライアント(speedygoshコマンド)が起動される。
  2. 引数を解釈する。
  3. スクリプトのpath、クライアント起動時のcwd、スクリプトのmtimeを適当に結合したもののsha1 digest値を取る。
  4. sessiondirが存在していないなら、sessiondirを生成する。
  5. 先ほどのdigest値に、カウント値0を追加して、各種ファイルのpathのprefix文字列を生成し、それを使ってロックを試みる。
  6. ロックに成功したら、該当するprefix文字列を持つsocketファイルの存在チェックを行う。
  7. socketファイルが存在していないなら、pipeを生成し、forkし、goshコマンドを使い、サーバ(speedygosh.server-estpモジュール)を起動する。この詳細は後述。
  8. socketファイルが存在しているか、生成されたなら、そこに対してunix domain socket接続を行い、ESTP通信によって環境変数と引数を送信する。その後、stdinをsocketに転送しつつ、socketからreadできるデータをstdoutに出力し続ける。
  9. socketからEOFが読み出されたら、最後まで正常終了したものとして、.exitファイルと.stderrファイルの有無を調べる。
  10. ロックファイル及び.exitファイル等の一時ファイルを削除し、exit値を返し、終了する。

サーバ(speedygosh.server-estpモジュール)サイド

  1. speedygoshコマンドから、各種の引数付きで起動される。具体的には大体、以下のようなコマンドで起動される(あとで引数を追加したりする可能性有り)。
    gosh -b -uspeedygosh.server-estp -Espeedygosh-server-boot -Eexit -- \
    script-file session-path-prefix timeout maxruns errorlog
    
  2. スクリプトファイルをuserモジュールに対してloadする。load時にエラーになったら、そのままエラー内容をstderrに流し、終了する。
  3. 正常にloadできたら、unix domain socketを生成し、socket生成まで完了した合図として、stdoutに改行を一つ流し、すぐにcloseする。
  4. その後、socketをselectで待機し、要求が来ると同時に先ほどloadしたスクリプトのmain手続きに渡し、処理を行う。
  5. これらの処理が完了したら、処理が完了したという合図として、socket接続をshutdownし、次の接続を待ち受ける。
  6. 一定時間しても次の接続が来ない場合は、ロックファイルを生成してロックを行い、socket及び関連ファイルを削除し、ロックファイルも削除して終了する。

一時ファイルの生成と削除の責任所在

ベンチマーク

TODO

ここに書いてある以外にも、ソースを「XXX」「TODO」「FIXME」「ToDo」で検索する事(この順で、優先度が高いものとする)。

作った感想など

バグレポート

gauche.nightプレゼン

gauche.nightでプレゼンしてきました。


最終更新 : 2013/10/24 12:05:48 JST