Ruby の非常に単純な Queue クラスを使用してさまざまな小さなスクリプトを作成し、DRb を使用して Ruby と JRuby プロセス間で Queue を共有しました。JRuby を使用して Scala (およびおそらく Java) からこれらにアクセスできると便利です。
jruby-complete.jar にアクセスするための Scala と JSR-223 インターフェイスをまとめました。
import javax.script._
class DRbQueue(host: String, port: Int) {
private var engine = DRbQueue.factory.getEngineByName("jruby")
private var invoker = engine.asInstanceOf[Invocable]
engine.eval("require \"drb\" ")
private var queue = engine.eval("DRbObject.new(nil, \"druby://" + host + ":" + port.toString + "\")")
def isEmpty(): Boolean = invoker.invokeMethod(this.queue, "empty?").asInstanceOf[Boolean]
def size(): Long = invoker.invokeMethod(this.queue, "length").asInstanceOf[Long]
def threadsWaiting: Long = invoker.invokeMethod(this.queue, "num_waiting").asInstanceOf[Long]
def offer(obj: Any) = invoker.invokeMethod(this.queue, "push", obj.asInstanceOf[java.lang.Object])
def poll(): Any = invoker.invokeMethod(this.queue, "pop")
def clear(): Unit = { invoker.invokeMethod(this.queue, "clear") }
}
object DRbQueue {
var factory = new ScriptEngineManager()
}
(java.util.Queue インターフェースにほぼ準拠していますが、Ruby クラスで提供されていない element と peek メソッドを実装していないため、インターフェースを宣言していません。)
これに関する問題は、型変換です。JRuby は Scala の文字列に問題ありません。これは Java 文字列であるためです。しかし、Scala Int または Long、または他の Scala タイプ (List、Set、RichString、Array、Symbol) のいずれか、またはその他のカスタム タイプを指定するとします。
これは不必要にハックに思えます: 確かに、JSR-223 API を使用せずに RMI/DRb 相互運用を行うためのより良い方法が必要です。offer メソッドがオブジェクトを、たとえば JSON 文字列にシリアル化し、toJson メソッドを持つオブジェクトのみの構造型を取るようにすることもできます。次に、JSON を解析する Ruby ラッパー クラス (または単に monkeypatch キュー) を記述します。
Java/Scala から DRb にアクセスしようとすることに意味はありますか? 実際のメッセージ キューをインストールする方が簡単なのでしょうか? (そうであれば、軽量な JVM ベースの MQ の提案はありますか?)