从 Scala(和 Java)访问 DRb 对象(例如 Ruby 队列)的最佳方式是什么?

发布于 2024-09-05 18:54:57 字数 1603 浏览 4 评论 0原文

我使用 Ruby 非常简单的 Queue 类构建了各种小脚本,并使用 DRb 在 Ruby 和 JRuby 进程之间共享队列。如果能够使用 JRuby 从 Scala(也许还有 Java)访问这些内容,那就太好了。

我已经将 Scala 和 JSR-223 接口组合在一起来访问 jruby-complete.jar。

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 接口,但我没有声明该接口,因为它没有实现 element 和 peek 方法,因为 Ruby 类不提供它们。)

问题在于类型转换。 JRuby 可以很好地处理 Scala 的字符串 - 因为它们是 Java 字符串。但是如果我给它一个 Scala Int 或 Long,或者其他 Scala 类型之一(List、Set、RichString、Array、Symbol)或其他自定义类型。

这看起来有些不必要的hacky:当然必须有一种更好的方法来进行 RMI/DRb 互操作,而无需使用 JSR-223 API。我可以这样做,以便 Offer 方法将对象序列化为 JSON 字符串,并采用仅具有 toJson 方法的对象的结构类型。然后我可以编写一个 Ruby 包装类(或只是 Monkeypatch Queue)来解析 JSON。

继续尝试从 Java/Scala 访问 DRb 有什么意义吗?安装一个真正的消息队列可能会更容易吗? (如果是这样,对基于 JVM 的轻量级 MQ 有什么建议吗?)

I have built a variety of little scripts using Ruby's very simple Queue class, and share the Queue between Ruby and JRuby processes using DRb. It would be nice to be able to access these from Scala (and maybe Java) using JRuby.

I've put together something Scala and the JSR-223 interface to access jruby-complete.jar.

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()
}

(It conforms roughly to java.util.Queue interface, but I haven't declared the interface because it doesn't implement the element and peek methods because the Ruby class doesn't offer them.)

The problem with this is the type conversion. JRuby is fine with Scala's Strings - because they are Java strings. But if I give it a Scala Int or Long, or one of the other Scala types (List, Set, RichString, Array, Symbol) or some other custom type.

This seems unnecessarily hacky: surely there has got to be a better way of doing RMI/DRb interop without having to use JSR-223 API. I could either make it so that the offer method serializes the object to, say, a JSON string and takes a structural type of only objects that have a toJson method. I could then write a Ruby wrapper class (or just monkeypatch Queue) to would parse the JSON.

Is there any point in carrying on with trying to access DRb from Java/Scala? Might it just be easier to install a real message queue? (If so, any suggestions for a lightweight JVM-based MQ?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

唠甜嗑 2024-09-12 18:54:57

安装企业消息队列是值得的,因为 DRB 和 ruby​​ 不是队列技术。

在我看来,你正在创造技术债务。

如果你想坚持走同样的道路,你可以使用他们放弃的八哥的推特队列。

我认为 Java 世界 JMS 中有大量可用的队列。

如果您编写了一个 DRB 服务器,那么您甚至可以做一个实现队列接口的数组就足够了,这非常简单!
然后适当缩放
http: //www.java-tips.org/java-se-tips/java.lang/array-based-queue-implementation-in-java.html

在我看来,坚持使用经过验证的企业技术,而不是未经验证的黑客技术,我已经通过艰难的方式学到了这一点。

Its worthwile to install a enterprise message queue because DRB and ruby is not the technology for Queuing.

In my opinion you are creating a tech debt here.

If you want to persist on the same path you can use the twitter queuing they abandoned starling.

I think there are heaps of queues available in the Java world JMS.

If you wrote a DRB server you could have sufficed even doing an array implementing the queue interface thats dead simple!
then scale appropriately
http://www.java-tips.org/java-se-tips/java.lang/array-based-queue-implementation-in-java.html

In my opinion stick to proven enterprise technologies and not hacky unproven ones, I have leanrt that the hard way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文