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

时间:2012-09-05 20:54:27

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

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

以前的版本是一个使用普通Python(相当难看的应用程序)的应用程序,其中包含对SQL的简单SQL请求。有一个表“jabber_queue”,所以在分离的脚本中,机器人每秒检查任何行,处理它(发送消息),删除。它简单而愚蠢,但没关系。

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

这是我可以做的几个版本:

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

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

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

  4. 对于我的问题中的这个词,我很抱歉,这只是一个脑力流。我看到了一些解决方案,但我确实需要来自更有经验的开发人员的建议和一些话。

1 个答案:

答案 0 :(得分: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. 创建了守护程序脚本starter- 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运行它。

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

    要为我的“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重写它。