Table Of Contents

Previous topic

RaSC動作の概要

Next topic

マルチコアCPUを生かして並列実行する

This Page

MessagePack RPCでユーザプログラムを呼び出す

ここでは,ユーザプログラムをRaSC上で稼働させることにより,ネットワークを介した呼び出しを可能とする手順を説明します. 呼び出しプロトコルには, MessagePack RPC を用います.

RaSC上で稼働させられるプログラムは, RaSCサービス化可能なプログラム で述べられたような条件を満たす必要があります. ここでは,そのような条件を満たす形態素解析エンジン MeCab を例に説明します.

RaSCサービスとしてユーザプログラムを起動する

まず RaSC のコアパッケージをダウンロードして解凍します. [1]

$ curl -o rasc-core-1.0.1.zip "http://alaginrc.nict.go.jp/rasc/cgi-bin/dl.cgi?name=rasc-core-1.0.1&type=zip"
$ unzip rasc-core-1.0.1.zip

解凍すると,以下のファイルが展開されます.:

rasc-core-1.0.1/
+ /lib
   + … (必須ライブラリ群)
+ logger.property (ロギング設定)
+ /WEB-INF
  + /serviceimpl
    + SampleService.xml (サービス定義XMLの例)
+ SampleClient.java (クライアントプログラムの例)
+ server.sh (起動スクリプト)

WEB-INF/serviceimpl 以下に置かれたサービス定義XMLのファイル名(拡張子を除いた部分)がサービス名になります.ここでは,MeCabをRaSCサービス化することを想定して,名称を変更します.

$ mv WEB-INF/serviceimpl/SampleService.xml WEB-INF/serviceimpl/MeCabService.xml

WEB-INF/serviceimpl/MeCabService.xml を開いて, 下記のように ___PATH_TO_PROGRAM___ となっている箇所に,実行したいユーザプログラムのコマンドラインを設定します.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="target"
    class="jp.go.nict.langrid.servicecontainer.handler.TargetServiceFactory">
    <property name="service">
      <bean class="jp.go.nict.rasc.wrapper.StandardInputService">
        <property name="cmdLine" value="___PATH_TO_PROGRAM___" />
        <property name="delimiterIn" value="\n" />
        <property name="delimiterOut" value="EOS\n" />
      </bean>
    </property>
  </bean>
</beans>

RaSCは, cmdLine プロパティに指定されたコマンドラインを実行します. delimiterIn は,改行が入力1単位のデリミタになっていることを表しています. delimiterOut プロパティは,文字列 “EOS” と改行がデリミタになっていることを表しています.(指定可能な項目については サービス定義XML を参照してください)

RaSCは,クライアントから受け取ったリクエストについて, delimiterIn プロパティに指定した文字列を付与してユーザプログラムの標準入力に書き込みます. また,ユーザプログラムの標準出力への出力から, delimiterOut プロパティに指定した文字列を発見し,そこまでを1件のリクエストに対応した出力であると見なします.

例えば, "今日はいい天気ですね" (改行無し)という文字列がクライアントから送信されると,その文字列に改行を付与してからMeCabの標準入力に書き込みます. MeCabは改行を受け取ってから処理を実行しますので,このような delimiterIn の指定は必須です. また,MeCabは1件の解析結果の末尾に "EOS\n" という文字列を出力しますので,この文字列を delimiterOut に指定しています. 他のユーザプログラムを使用する場合は,そのプログラムの振る舞いに応じて delimiterIn, delimiterOut の設定が必要になります.

パッケージを展開したパスで,下記のコマンドを実行すると,RaSCサービスが起動します.一つ目の引数はサービス名であり,二つ目の引数はポート番号です.

$ sh ./server.sh MeCabService 19999 start

なお,停止は下記のコマンドで行います.

$ sh ./server.sh MeCabService 19999 stop

RaSCサービスを呼び出す

RaSCサービスを呼び出す,以下のようなJavaによるクライアントが同梱されています(SampleClient.java).

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;

import jp.go.nict.langrid.client.msgpackrpc.MsgPackClientFactory;
import jp.go.nict.wisdom.wrapper.TextAnalysisService;

public class SampleClient {
  public static void main(String[] args) throws Exception {
    MsgPackClientFactory factory = new MsgPackClientFactory();

    TextAnalysisService client = factory.create(TextAnalysisService.class,
              new InetSocketAddress(args[0], Integer.parseInt(args[1])));
    String ret = client.analyze(args[2]);

    System.out.println(ret);
    factory.close();
  }
}

String analyze(String input) という形式の呼び出しインターフェースが TextAnalysisService.class に定義されており,それを呼び出しています.

下記のように,クライアントプログラムをコンパイルし,実行します.

$ javac -classpath ./lib/*: SampleClient.java
$ java -cp ./lib/*: SampleClient localhost 19999 今日はいい天気ですね
今日  名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
は    助詞,係助詞,*,*,*,*,は,ハ,ワ
いい  形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
天気  名詞,一般,*,*,*,*,天気,テンキ,テンキ
です  助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
ね    助詞,終助詞,*,*,*,*,ね,ネ,ネ

2 06, 2014 6:37:04 午後 org.msgpack.rpc.transport.PooledStreamClientTransport
情報: Close all channels

第一引数にサービスを起動したホストを,第二引数にはポートを指定します.第三引数に与えた文字列が, delimiterIn を付与した上でユーザプログラムの標準入力に書き込まれます. また,ユーザプログラムの( delimiterOut までの)標準出力への出力が, analyze() の戻値として返されます.

うまくいかないときには

[1]このパッケージは,GitHubに登録されたプロジェクトpkg_coreから生成されたものです.