Rails和XMPP(Jabber)bot:关于(异步?)队列的建议



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

以前的版本是一个使用普通Python(相当丑陋的应用程序)的应用程序,并向DB发出普通SQL请求。有一张桌子";jabber_queue";,因此,在分离的脚本中,bot每秒都在检查是否有任何行,处理它(发送消息),删除它。这很简单也很愚蠢,但还好。

现在我明白了,我需要将这个bot功能集成到Rails中(至少要使用RSpec)。

这是我关于如何做到这一点的几个版本:

  1. 使用分离的异步队列解决方案。例如,Resque。使用分离的Ruby脚本并将事件推送到Resque中,在应用程序中弹出事件(不依赖于DB,因此很容易与RSpec测试和测试DB配合使用)。但这让我的应用程序有点臃肿——我需要使用第二个DB,这需要大量的内存和CPU额外的要求——这将是我的问题的开销。此外,我不想支持额外的";事物;对于这个应用程序,我知道,它可以用更简单的方法来完成。

  2. 使用delayed_job(使用当前AR DB的队列解决方案)。但我不知道如何在分离的脚本中获得Rails应用程序的当前AR DB。不管怎样,这是一种肮脏和丑陋的方式。

  3. 启动XMPP机器人WITHINTRails应用程序,作为后台工作人员。因此工人将获得";当前";AR(在测试的情况下,用于测试DB)。但我根本不知道该怎么做。我已经找到了一个Navvy,但我需要在Rails的某个地方放一个字符串,比如"Navvy::Job.enqueue(奶牛,:说话)";,我不知道哪里是最好的地方,从RSpec测试开始;rails服务器";。此外,还有一个BackGroundDRb,但这个项目与Navvy类似,也处于非活动状态。使用stackoverflow上的搜索,我发现了和我类似的问题,但解决方案让我找到了background_job,它可以在后台进行任何操作,但我仍然不知道如何在分离的脚本中获得当前的AR DB访问权限。

我很抱歉我的问题中有这么多单词,这只是一个想法。我看到了一些解决方案,但我真的需要更有经验的开发人员的建议和建议。

因此,使用第三种方法解决了这个问题。

  1. 我创建了一个用于处理bot命令和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中使用我的任何型号!此外,对于队列,我使用的是小模型XMPPJob,其字段为jtype(例如,"xmpp_message")、body("嘿!")、to("john@jabber.com")。使用limit(5).each do |job| case jtype ...在bot类的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重写它。

最新更新