我正在构建一个服务,它基本上允许用户与机器人聊天,然后机器人对用户发送的聊天进行一些奇怪的处理,并最终回复一些有意义的数据。基本上类似于Aardvark的用法(?)去工作。
我有机器人工作,现在就在听,我有一个单独的rails应用程序,它将完成所有其他繁重的工作。这两个部分各自都工作得很好,现在我只能把这两个部分连接起来。我的想法是通过Resque将机器人(基本上是一个小红宝石脚本)与rails应用程序接口--任何进来的东西都会进入队列,被捡起来,然后结果又被推回队列,然后脚本会回复结果。
我不太清楚如何建立这个界面:
我知道这些可能是非常琐碎的问题,但我很难理解哪一个更好,以及如何让设置进行。
发布于 2013-01-28 16:46:09
在Rails应用程序和这个bot守护进程之间有三种通信方式:
当您正在排队并将Resque作业从各种作业队列中取出时,您只是通过一个API读取/写入共享的Redis数据库。机器人和Rails应用程序都通过网络与Redis DB对话。
我建议将机器人直接作为ruby进程或由monit管理的rake任务运行。听起来你已经知道怎么做了。
发布于 2013-02-03 04:36:41
我认为这里的主要问题是,您需要另一种消息传递解决方案(IPC,而不是IM),而不是试图弯曲Resque,即“只是”一个队列。其中一些选项是amqp创业板 (AMQP协议)或zmq宝石 (ZeroMQ协议),但您也可以通过Ruby库套接字类(好例子)使用普通的UNIX套接字。他们都有不同的优点和缺点,所以这取决于你和你的需要。
交互可能看起来像这样:
可能会像往常一样发生一些变化。例如,我认为你根本不需要Resque。机器人可以直接将请求传递给Rails应用程序。然而,这取决于负载、响应时间、当前体系结构等等。也许Resque作业可以等待Rails应用程序返回结果,然后作业(而不是Rails应用程序)使用IPC。还有其他的变体…
我是否需要编写一个rake任务来启动/停止/重新加载机器人?
不,你没有。这取决于你如何和什么时候运行它。毕竟,Rake可以被看作是将多个Ruby脚本放在一起并在它们之间创建依赖关系的一种方便的方式。如果您认为机器人周围还有其他任务,而不仅仅是运行它(一些清理、部署等),那么为了方便起见,使用Rake会更好。如果您还没有,那么refactor bot的类逻辑并使用Rake任务来初始化它。但是,如果您不使用它,只需按-is运行脚本(使用monit、自定义init.d脚本、即席脚本等),也是可以的。
如果我在没有rake的情况下运行它(据说是一个由Monit监视的独立进程),那么我如何与Resque接口或访问rails模型?
对此没有任何影响。从操作系统的角度来看,如果通过Rake运行Resque,通过Rake运行机器人或者作为独立脚本运行Rake并不重要。无论如何,它们将是不同的过程。此外,请记住,Resque需要Redis跑到某个地方。
我知道这些可能是非常琐碎的问题
一点也不。我认为这需要一段时间才能被认为是微不足道的问题。
发布于 2015-12-17 11:02:54
您可以将代码放在初始化程序上运行,并且可以完全访问所有Rails模型或库。
这样,您不需要在bot和Rails应用程序之间进行“通信”,因为您的bot位于Rails应用程序中。
样板代码就像:
配置/初始化器/背景_app_tasks.rb
class BackgroundWorker
#-------------------------------
def initialize(operation='normal')
@exit = false
@lock = Mutex.new # For thread safety
@thread = nil
say "Starting in '#{operation}' mode..."
case operation
when 'normal'
@thread = Thread.new() { loopme }
when 'cleanup'
@thread = Thread.new() { cleanup }
when 'nothing'
#startup without threads
end
@thread.run if @thread
end
#-------------------------------
def exit!
begin
return if @exit # #stop?
say "Exiting #{}, waiting for mutex..."
@lock.synchronize {
say "exiting thread #{@thread.to_s || '<sem nome>' }..."
@exit = true # #stop
}
rescue Exception => e
exceptme(e)
end
end
#-------------------------------
def loopme
at_exit { exit! }
i=0; ok=false;
nap = 30
while true do
begin
break if @exit
i+=1
#lock mutex for processing...
@lock.synchronize {
#.... do some work ....
}
rescue StandardError => e
#....
end
sleep(nap)
end
end
end #class
# ------ M A I N --------
Thread.abort_on_exception=false
e = BackgroundWorker.new(OPERATION)https://stackoverflow.com/questions/14504441
复制相似问题