【问题标题】:Rails and XMPP(Jabber) bot: advice about (asynchronous?) queueRails 和 XMPP(Jabber) 机器人:关于(异步?)队列的建议
【发布时间】:2012-09-05 20:54:27
【问题描述】:

所以,我正在使用 Rails 构建一个小型应用程序。我需要使用 XMPP proto 通过一些命令通知用户来更改用户状态。

以前的版本是一个使用纯 Python 的应用程序(相当丑陋的应用程序),带有纯 SQL 请求到 DB。有一个表“jabber_queue”,所以在单独的脚本中,机器人每秒检查任何行,处理它(发送消息),删除。这既简单又愚蠢,但没关系。

现在我明白了,我需要将此机器人功能集成到 Rails 中(至少要与 RSpec 一起使用)。

这是我的几个版本:

  1. 使用分离的异步队列解决方案。例如,雷斯克。使用单独的 Ruby 脚本并将事件推送到 Resque,在应用程序中弹出事件(不依赖于 DB,因此很容易适应 RSpec 测试和测试 DB)。但这使我的应用程序有点臃肿 - 我需要使用具有大量内存和 CPU 额外要求的第二个数据库 - 这将是我的问题的开销。另外,我不想为这个应用程序支持额外的“东西”,我知道,它可以更简单地完成。

  2. 使用延迟作业(使用当前 AR DB 的队列解决方案)。但我不知道如何在单独的脚本中获取 Rails 应用程序的当前 AR DB。无论如何,这是一种肮脏和丑陋的方式。

  3. 启动 XMPP bot WITHIN Rails 应用程序,作为后台工作者。所以工人将可以访问“当前”AR(在测试的情况下,测试数据库)。但我根本不知道该怎么做。我找到了Navvy,但我需要在 Rails 的某个位置开始一个字符串,例如“Navvy::Job.enqueue(Cow, :speak)”,我不知道在哪里将是最好的地方,从 RSpec 测试和“rails 服务器”开始。此外,还有一个 BackgrounDRb,但这个项目类似于 Navvy 并且也处于非活动状态。在stackoverflow上使用搜索,我发现了与我类似的问题,但解决方案将我引导至background_job,它可以在后台进行任何操作,但我仍然不知道如何在单独的脚本中获取当前的AR DB访问权限。

我很抱歉我的问题中出现了这么多字,这只是脑力激荡。我看到了一些解决方案,但我真的需要更有经验的开发人员的建议和一些话。

【问题讨论】:

  • 从一些谷歌结果中我发现了使用分叉延迟作业的想法:用我的工作设置一个类(XMPP 机器人的生命周期,我理解正确),但还会有另一个问题 -我需要在生命周期任务中处理其他任务(例如:send_xmpp_msg)。所以我需要检查另一个任务中的任务队列。所以我需要创建另一个队列。哦,我的上帝,看来,我需要另一个解决方案。有什么想法吗?

标签: ruby-on-rails xmpp message-queue background-process


【解决方案1】:

所以,这是通过第三种方式解决的。

  1. 我创建了一个类来处理机器人命令和 AR 模型 - awesomo.rb。没什么特别的,真的。我把它放在 Rails 项目的/lib/ 中。其次,

  2. 创建配置文件,方便设置密码和 JID - config/awesomo.yml

    development:
      xmpp_jid: ...
      xmpp_password: ...
    
  3. 我为我的机器人创建了一个守护进程 - awesomo_daemon.rb。同样,在/lib/。这是它包含的内容:

    #preload rails environment
    require File.expand_path(File.join(File.dirname(__FILE__),
         '..', 'config', 'environment'))
    
    #load xmpp bot class
    require 'awesomo_daemon'
    
    #load xmpp bot configuration file for current environment
    AWESOMO_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__),
        '..', 'config', 'awesomo.yml'))[Rails.env]
    
    #apply configuration before singleton will be initiated
    Awesomo.setup AWESOMO_CONFIG['xmpp_jid'], AWESOMO_CONFIG['xmpp_password']
    
    loop {
      Awesomo.instance.idle
      sleep 1
    }
    
  4. 已创建守护程序脚本启动器-script/awesomo

    #!/usr/bin/env ruby
    require 'rubygems'
    require 'daemons'
    Daemons.run "lib/awesomo_daemon.rb", dir_mode: :normal,
        dir: File.join(File.dirname(__FILE__), '..', 'tmp', 'pids')
    
  5. 只需使用命令script/awesomo start 运行即可。

我可以在awesomo.rb 中使用我的任何模型!另外,对于队列,我正在使用带有字段 jtype(例如,“xmpp_message”)、body(“hey!”)、to(“john@jabber.com”)的小模型 - XMPPJob。在 limit(5).each do |job| case jtype ... 的机器人类的 awesomo.rb idle 函数中获取它。

要为我的“awesomo”发布任何新工作,我正在使用函数send_message

def self.send_message to, body
  xmppjob = XmppJob.new :jtype => "xmpp_message", :body => body, :to => to
  xmppjob.save
end

除了 XMPP 库 (xmpp4r-simple) 本身之外,一切都运行良好,但我很快会使用 xmpp4r 重写它。

【讨论】:

  • +1 分享您的解决方案和广泛的答案:)
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2013-01-08
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
相关资源
最近更新 更多