各々のDroonga Engineプラグインは、それ自身のためのハンドラーを持つことができます。ハンドリング・フェーズでは、ハンドラーはリクエストを処理して結果を返すことができます。
例えば、「foo」という名前のプラグインにハンドラーを定義する場合は以下のようにします:
require "droonga/plugin"
module Droonga::Plugins::FooPlugin
extend Plugin
register("foo")
define_single_step do |step|
step.name = "foo"
step.handler = :Handler
step.collector = Collectors::And
end
class Handler < Droonga::Handler
def handle(message)
# リクエストを処理するための操作
end
end
end
ハンドラーを定義するための手順は以下の通りです:
Droonga::Plugins::FooPlugin
)を定義し、プラグインとして登録する。(必須)Droonga::SingleStepDefinition
を使い、実装しようとしているハンドラーに対応する「single step」を定義する。(必須)Droonga::Handler
を継承したハンドラークラス(例:Droonga::Plugins::FooPlugin::Handler
)を定義する。(必須)#handle
として定義する。(任意)プラグイン開発チュートリアルも併せて参照して下さい。
ハンドラーは以下のように動作します:
#handle
メソッドが、リクエストの情報を含むタスクメッセージを伴って呼ばれる。
上記の通り、Droonga Engineは各リクエストに対してその都度ハンドラークラスのインスタンスを生成します。
ハンドラー内で発生したすべてのエラーは、Droonga Engine自身によって処理されます。エラー処理も併せて参照して下さい。
action.synchronous
(真偽値, 省略可能, 初期値=false
)action.synchronous = true
の指定を伴うことになる。Droonga::SingleStepDefinition
このクラスは、ハンドラーに対応するstepの詳細を記述する機能を提供します。
#name
, #name=(name)
step自身の名前を記述します。値は文字列です。
Droonga Engineは、メッセージのtype
に一致するname
を持つstepが存在する場合に、入力メッセージをコマンドのリクエストとして扱います。
言い換えると、このメソッドはstepに対応するコマンドの名前を定義します。
#handler
, #handler=(handler)
特定のハンドラークラスをstepに紐付けます。 ハンドラークラスは以下のいずれかの方法で指定します:
Handler
や Droonga::Plugins::FooPlugin::Handler
のような、ハンドラークラス自体への参照。
当然ながら、参照先のクラスはその時点で定義済みでなければなりません。:Handler
のような、その名前空間で定義されているハンドラークラスのクラス名のシンボル。
この記法は、stepを先に記述して後からハンドラークラスを定義する場合に有用です。"Droonga::Plugins::FooPlugin::Handler"
のような、ハンドラークラスのクラスパス文字列。
この記法もまた、stepの後でハンドラークラスを定義する場合に有用です。ハンドラークラスをシンボルまたは文字列で指定した場合、参照先のクラスは、Droonga Engineが実際にそのstepを処理する時点までの間に定義しておく必要があります。 Droonga Engineがハンドラークラスの実体を見つけられなかった場合、またはハンドラークラスが未指定の場合には、Droonga Engineはそのリクエストに対して何も処理を行いません。
#collector
, #collector=(collector)
特定のコレクタークラスをstepに紐付けます。 コレクタークラスは以下のいずれかの方法で指定します:
Collectors::Something
や Droonga::Plugins::FooPlugin::MyCollector
のような、コレクタークラス自体への参照。
当然ながら、参照先のクラスはその時点で定義済みでなければなりません。:MyCollector
のような、その名前空間で定義されているコレクタークラスのクラス名のシンボル。
この記法は、stepを先に記述して後からコレクタークラスを定義する場合に有用です。"Droonga::Plugins::FooPlugin::MyCollector"
のような、コレクタークラスのクラスパス文字列。
この記法もまた、stepの後でコレクタークラスを定義する場合に有用です。コレクタークラスをシンボルまたは文字列で指定した場合、参照先のクラスは、Droonga Engineが実際にそのstepの結果を集約する時点までの間に定義しておく必要があります。 Droonga Engineがコレクタークラスの実体を見つけられなかった場合、またはコレクタークラスが未指定の場合には、Droonga Engineは処理結果を集約せず、複数のメッセージとして返します。
コレクターの説明も併せて参照して下さい。
#write
, #write=(write)
stepがストレージ内の情報を変更し得るかどうかを記述します。 リクエストがストレージ内のデータを変更することを意図する物である場合、そのリクエストはすべてのreplicaで処理される必要があります。 それ以外の場合、Droonga Engineは結果をキャッシュしたり、CPUやメモリの使用量を削減するなどして、処理を最適化することができます。
取り得る値:
true
: そのstepではストレージの内容が変更される可能性がある事を示す。false
: そのstepではストレージの内容が変更される可能性はない事を示す。(初期値)”#inputs
, #inputs=(inputs)
(未稿)
#output
, #output=(output)
(未稿)
Droonga::Handler
これはすべてのハンドラーに共通の基底クラスです。独自プラグインのハンドラークラスは、このクラスを継承する必要があります。
#handle(message)
このメソッドは、Droonga::HandlerMessage
でラップされたタスクメッセージを受け取ります。
プラグインは、このタスクメッセージのメソッドからリクエストの情報を読み取る事ができます。
この基底クラスにおいて、このメソッドは何もしない単なるプレースホルダとして定義されています。 メッセージを処理するには、以下のようにメソッドを再定義して下さい:
module Droonga::Plugins::MySearch
class Handler < Droonga::Handler
def handle(message)
search_query = message.request["body"]["query"]
...
{ ... } # the result
end
end
end
Droonga Engineは、このメソッドの戻り値を処理の結果として扱います。 結果の値は、レスポンスのbodyの組み立てに使われ、Protocol Adapterに送られます。
Droonga::HandlerMessage
このクラスはタスクメッセージに対するラッパーとして働きます。
Droonga Engineは送られてきたリクエストのメッセージを解析し、そのリクエストを処理するための複数のタスクメッセージを作成します。 1つのタスクメッセージは、リクエストの実体、step、後続するタスクの一覧などの情報を持ちます。
#request
このメソッドはリクエストメッセージを返します。例:
module Droonga::Plugins::MySearch
class Handler < Droonga::Handler
def handle(message)
request = message.request
search_query = request["body"]["query"]
...
end
end
end
@context
対応するボリュームのストレージを示す、Groonga::Context
のインスタンスへの参照。
Rroongaのクラスリファレンスも併せて参照して下さい
@context
を経由して、Rroongaのすべての機能を利用できます。
例えば、以下は指定されたテーブルのすべてのレコードの数を返す例です:
module Droonga::Plugins::CountRecords
class Handler < Droonga::Handler
def handle(message)
request = message.request
table_name = request["body"]["table"]
count = @context[table_name].size
end
end
end