==== FAQs ==== .. contents:: 一覧 :local: :depth: 1 .. _faq_pipe: 複数のユーザプログラムをパイプで接続してRaSC上で動作させるには --------------------------------------------------------- パイプでの接続を記述したシェルスクリプトを用意するのが簡単です.例えば,構文解析システム `KNP `_ を動作させるには,以下のようなシェルスクリプトを用意します. .. code-block:: bash #!/bin/bash juman | knp このスクリプトを ``run_knp.sh`` として保存した上で,以下のようにサービス定義XMLを用意します. .. code-block:: xml :emphasize-lines: 8 :doc:`rasc_core` の手順に従い,このサービス定義XMLを指定してRaSCサービスを起動すると,パイプで接続された複数のユーザプログラムをRaSC上で稼働させることができます. .. _faq_pipe_in: パイプでの入力を並列処理する --------------------------- :doc:`rasc_parallel_local` に従って,並列実行の設定をしたRaSCサービスを起動します. 以下のようなJavaプログラムでRaSCサービスを呼び出すことで,標準入力からの読み取りと,並列処理を行えます. .. code-block:: java import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.util.Arrays; import org.apache.commons.lang.StringUtils; import jp.go.nict.langrid.client.msgpackrpc.MsgPackClientFactory; import jp.go.nict.wisdom.wrapper.api.TextAnalysisService; public class RaSCClient { public static void main(String[] args) throws Exception { try(MsgPackClientFactory factory = new MsgPackClientFactory()){ TextAnalysisService client = factory.create( TextAnalysisService.class, new InetSocketAddress(args[0], Integer.parseInt(args[1]))); try(InputStreamReader isr = new InputStreamReader(System.in, "UTF-8"); BufferedReader br = new BufferedReader(isr)) { String[] list = new String[1000]; int count = 0; while((list[count] = br.readLine()) != null) { count++; if (count == list.length){ String[] ret = client.analyzeArray(list); System.out.println(StringUtils.join(ret, "\n")); count = 0; } } if(count > 0){ String[] ret = client.analyzeArray(Arrays.copyOf(list, count)); System.out.println(StringUtils.join(ret, "\n")); } } } } } コンパイルと実行には,`RaSCコアパッケージ `_ を使うのが簡単です(手順は :doc:`rasc_core` を参照してください).以下のコマンドでコンパイルできます. .. code-block:: bash javac -cp lib/*: RaSCClient.java ホスト名とポートを指定し,以下のように利用できます.ここでは,ホストは ``localhost``, ポートは ``19999`` でRaSCサービスが起動しているものとします. .. code-block:: bash cat INPUT_TXT | java -cp ./lib/*: RaSCClient localhost 19999 Perl, Python, RubyからRaSCサービスを呼び出すには ----------------------------------------------- :doc:`rasc_msgpack_various_lang` を参照してください. .. _faq_whitespace_in_cmd: 空白を含むディレクトリやファイル名をコマンドラインに指定するには ---------------------------------------------------------- サービス定義XMLに指定するコマンドラインで,ディレクトリ名やファイル名に空白が含まれると,:doc:`rasc_core` に示した記述では正しく動作しません. プロパティ cmdLine の代わりに,cmdArray を使って指定してください.以下は,Windows環境におけるmecabのデフォルトパスを指定する例です. .. code-block:: xml C:\Program Files\Mecab\bin\mecab -O wakati cmdArrayプロパティとcmdLineプロパティが同時に設定されるとエラーになります. "EOS"などの終端記号を結果に含めたい ---------------------------------- :doc:`service_xml` の ``includeDelim`` を ``true`` にしてください. RaSCサービスの死活を確認する ---------------------------- ``String getStatus()`` というメソッドを呼ぶと,設定されたコマンドラインと,プールされたプロセス数が返されます. 以下に呼出例を示します. ``SERVICE_HOST``, ``SERVICE_PORT`` はそれぞれ,RaSCサービスが起動しているホストとポートであるとします. 呼出例: Java .. code-block:: java TextAnalysisService client = factory.create(TextAnalysisService.class, new InetSocketAddress(SERVICE_HOST, SERVICE_PORT)); String ret = client.getStatus(); 呼出例: Perl .. code-block:: perl my $client = AnyEvent::MPRPC::Client->new( host => "SERVICE_HOST", port => "SERVICE_PORT" ); my $ret = $client->call('getStatus')->recv; 呼出例: Python .. code-block:: python client = msgpackrpc.Client(msgpackrpc.Address("SERVICE_HOST", SERVICE_PORT)) ret = client.call('getStatus') :doc:`rasc_core` で起動したMeCabサービスの場合の,結果の例を示します.サービス定義XMLに設定されたコマンドラインと,実行中のプロセス数・上限のプロセス数が返されます. .. code-block:: bash Command line: /usr/local/bin/mecab Pooled processes: 1 / 20 .. ユーザプログラムの実行が遅い ---------------------------- いくつかのパターンがある... - analyzeArrayで一括送信 - 実装を変えて,一括でユーザプログラムに渡すようにする - データの単位を変える RaSCサービスが応答しない ------------------------ クライアントから呼び出しを行っても結果が得られず,サービス定義XMLに設定したタイムアウト時間が経過してからエラーが返ることがあります. ユーザプログラムが実際には短時間で終了しているとすると,以下のような問題が考えられます. - ユーザプログラムに入力デリミタが正しく送信できていない - ユーザプログラムが出力する,出力デリミタを認識できていない 入力デリミタ,出力デリミタは, :doc:`service_xml` に定義された,入力や出力の単位を認識するための区切りです. 例えば,ユーザプログラムが入力デリミタとして ``[END_OF_INPUT]\n`` (末尾に改行あり)という文字列を認識するとします. このとき,RaSCの設定で ``[END_OF_INPUT]`` (末尾に改行無し) を設定してしまうと,ユーザプログラムは改行コードを待ち続け,応答がなくなったように見えます.RaSCは設定した時間以上応答がない場合,プログラムを終了させ,再起動します(再起動が行われたことは,RaSCサービスのログに出力されます). 同様の問題は,出力についても発生します.例えば,ユーザプログラムが出力デリミタとして ``[END_OF_OUTPUT]`` (末尾に改行無し)という文字列を出力するとします. 一方,RaSCの設定で ``[END_OF_INPUT]\n`` (末尾に改行あり) を設定してしまうと,RaSCは改行コードを待ち続けます. RaSCサービスからの応答がない場合には,入出力デリミタ(改行コードの有り無し,改行コードの種類),クライアントからの呼び出しにおける入力をチェックしてみてください. 同時に複数のリクエストを受けると何がおきるか ----------------------------------------- :ref:`rasc_service_structure` に説明があります. 起動するプログラムのプロセス数の上限,タイムアウト時間の設定は :doc:`service_xml` を参照してください. .. RaSCの動作状態を知りたい ------------------------ - ログファイルのロケーション - ログレベルの設定 - モニタリング機構説明へのリンク どんなユーザプログラムならRaSC上で動作するか -------------------------------------------- :ref:`rasc_ready_program` に説明があります. .. _faq_modify_program: 既存ツールをRaSCで動かすように改修するには ------------------------------------------ ユーザプログラムをRaSCサービス上で稼働させるには,以下が必要です. - 入出力に標準入出力を使用する - 入出力のデリミタを決める - 1単位の入力を受けても終了しないようにする. 以下は,これを実現するためのCRF++の改修例です. CRF++には標準入力を使用するオプションがあるため,入出力のデリミタを決めます.ここでは,入力のデリミタに ``[END_OF_INPUT]``, 出力のデリミタに ``EOS`` を用いるとします. そのため,下記のソースコードのハイライトされた箇所を追加し,1行読み込んだ内容が ``[END_OF_INPUT]`` だった場合に ``EOS\n`` を標準出力に書き込む処理を加えます. .. code-block:: cpp :emphasize-lines: 12-15 CRF++-0.58/tagger.cpp bool TaggerImpl::read(std::istream *is) { scoped_fixed_array line; clear(); for (;;) { if (!is->getline(line.get(), line.size())) { is->clear(std::ios::eofbit|std::ios::badbit); return true; } if(std::strcmp(line.get(), "[END_OF_INPUT]") == 0){ std::cout << "EOS\n"; return true; } if (line[0] == '\0' || line[0] == ' ' || line[0] == '\t') { break; } if (!add(line.get())) { return false; } } return true; } 大量のデータをRaSCサービスで処理するには ---------------------------------------- サイズの大きいデータを一度に処理しようとすると,バッファが溢れ,エラーになることがあります. :doc:`service_xml` の設定で,バッファサイズを変更することができます. .. ユーザプログラムを呼び出さないRaSCサービスを作る ------------------------------------------------ - Javaネイティブの場合の方法を説明 - Stanford POS Taggerの内容をかく 文字化けする ------------ 利用するユーザプログラムによっては,環境変数 LANG が ``ja_JP.UTF-8`` でないと正しく動作しないことがあります. .. _faq_set_env_vars: 環境変数を設定するには ---------------------- サービス定義XMLにパラメータ ``environment`` を定義することで,実行されるプログラムの環境変数を設定できます,(バージョン 1.0.2 以降). .. code-block:: xml VALUE1 VALUE2/value>