カスタム検索

2008年7月17日木曜日

BlazeDSヤバイ。まず広い。

grails + blazeDs なテスト

・適当なアプリを作成
grails create-app flexremote
cd flexremote

・flex pluginをインストール
grails install-plugin flex

・サービスを作成


class BookService {
static expose = ['flex-remoting']

def getBooks() {
return Book.list();
}
}


expose = ['flex-remoting']
にしておくと flex plugin が自動的に amf を配備してくれる。
これをFlex(AIR)側 remoteObject として定義してやると、サービスの中のメソッドが自由に呼べるようになる。


<mx:RemoteObject id="srv"
destination="bookService"
endpoint="http://localhost:8080/flexremote/messagebroker/amf"
result="resultHandler(event)"
fault="faultHandler(event)" />

<mx:Script>
<![CDATA[
srv.getProducts();
]]>
</mx:Script>



desitination はサービス名、endpoint に amf のURLを指定。
GrailsのDomainと同じフィールドを持つ class を作成しておけば、自動的にバインドされてハッピー。

ココにすばらすぃサンプルがあります。

さっくり速度検証もしてみました。
10000件のデータを同じGrailsアプリから blazeDS , WebService , Http(JSON)で投げてみました。

結果は blazeDS の圧勝。

WebServiceも通信部分だけなら早かったんですが、Modelにバインドすると結局 blazeDS の倍ぐらいかかります。
JSONは通信もバインドもかなり差をつけられた感じです、、、
まぁモデルをStringに置き換えてStringをパースして更にモデルにしてと明らかにステップ数が多いのでしょうがないですね。

Grailsでファイル監視

特定のフォルダを一定時間毎に監視して処理をするサンプルです。

・適当なアプリを作成します。
grails create-app qtest

・監視には quartz を使いますので、quartz plugin をインストールします。
cd qtest
grails install-plugin quartz

・quartz plugin が提供するコマンドを使って、適当な job を作成します。
grails create-job searchFile

grails-app/jobs/SearchFileJob.groovy が作成されます。
class名が @artifact.name @ になっているので、これを SearchFileJob に直し、監視設定を記述します。


class SearchFileJob {
 // ここは将来的にダイナミックに定義できるようになるらしい
 static triggers = {
  // 起動から3000ミリ秒後に処理を開始、1024ミリ秒毎にexecute()を実行
  simpleTrigger startDelay:3000, timeout:1000
 }

 def execute() {
  // この中が実行される
 }
}


・次に実際の処理を記述していきます。
指定したフォルダに .txt ファイルをみつけると、別のフォルダに移動してくれるという単純なサンプルを作ってみます。
execute() を以下のようにします。


def execute() {
// 監視するパスを設定
def _path = new File("/opt/job")
def _dest = new File("/opt/job/dest")

// パスが存在し、かつディレクトリであるか
if(_path.exists() && _path.isDirectory()) {
// フォルダ内のファイルを取得し、最終更新日が古いものからループをかける
def list = _path.listFiles()
list.sort{ it.lastModified() }.each { _file ->
// ロックファイルでないか確認
if(!_file.getName().toLowerCase().endsWith(".lock")) {
// 拡張子が .txt のものであれば処理をする
if(_file.getName() =~ ".*\\.[Tt][Xx][Tt]") {
// ロックファイルがあるか確認
def lock = new File(_file.getAbsolutePath()+".lock")
if(!lock.exists()) {
// ロックファイルを作成
lock.write("locked")

// ここに実際の処理を書く
def _endFile = new File(_dest,_file.getName())
_file.renameTo(_endFile)

// 処理が終わったらロックファイルを削除する
if(_endFile.exists()) {
lock.delete()
}
}
}
}
}
}
}


途中で ファイル名+.lock のファイルを作成していますが、
これは一回の処理に時間がかかる場合や、監視プログラム自体をクラスタ化した場合に、
同じファイルを二度処理しないように判別する為に使っています。
クラスタ化しない場合には変数で管理しても良いです。

他のクラス同様、クラスの注入を行えるので、 def grailsApplication を記述しておけば Config.groovy からのロードなんかも出来ます。