我目前正在管理一个运行在rails 1.2.7上的遗留rails应用程序。其中一个功能是允许人们上传声音,并使用命令行工具使用反引号对其进行转换。目前,我使用AJAX轮询通过控制器操作来管理转换,但我遇到了超时问题,这意味着控制器操作的最后元素根本不会发生。
这是一个需要低开销的系统,我可以使用什么来管理这个后台转换,然后在一个事件系统中响应由后台转换产生的问题?我正在寻找eventmachine,但我仍然不是100%使用它,有没有其他类型的基于异步任务的系统我可以使用?
发布于 2011-04-06 11:36:41
首先,哇,Rails 1.2.7。我在工作中有一个类似老旧的应用程序,我正在慢慢升级到Rails3。这个东西变化太快了。
这绝对是个有趣的问题。有很多方向你可以这样做,我不确定哪一个是最好的,因为我不确定我理解你的过程。所以我会推荐几个。我的理解是1)上传文件,2)开始转换,3)通过ajax轮询报告转换状态。
首先,正如您已经发现的,在Rails控制器操作中运行转换实用程序绝对不是可行的方法。1)您的Web服务器或浏览器可能会终止请求,2)大多数Rails部署允许每个应用程序一次只有一个请求,这意味着如果您希望5个用户同时上传,您需要运行5个应用程序副本。显然,这是不能扩展的。
你的“上传”动作应该尽可能快。它应该1)上传文件,2)调度或启动一个“转换作业”,由其他进程来处理。然后,您的轮询操作将只报告该作业的状态。当然,问题是另一个过程应该是什么。
Idea 1 http://geekblog.vodpod.com/2007/08/17/background-processing-in-rails/可能是一个很好的起点,尽管我不能保证这种方法。
Idea 2我做过类似的事情,所以我可以给出更多细节。而且它的伸缩性可能更好。使用Sinatra或Async Sinatra构建一个轻量级的配套应用程序。你的Rails应用程序会在数据库中为上传的文件记录一个作业,但之后它的部分就完成了。您的Sinatra应用程序使用EventMachine,将每隔几秒钟轮询数据库并启动新作业。您可能希望将其限制为n个并发作业,这样您就不会DOS您自己的机器:)然后您的用户可以轮询您的Sinatra应用程序以获得他们的转换状态。
Ruby 3类似于2,但它不是配套的网络应用程序,它只是一个使用EventMachine的小程序。你只需要在你的服务器上启动这个程序,让它永远运行。每个作业都会将其状态写回数据库,用户可以通过Rails应用程序对其进行轮询。我想这是我的最爱。线框:
#!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
# Returns new jobs from the database
def new_jobs
[]
end
# Convert the file
def convert(job)
`convert #{job.path}`
job
end
# Callback when conversion is complete
def callback(job)
puts "Finished #{job.path}!"
end
EventMachine::run do
# Run every 5 seconds
EventMachine::add_periodic_timer(5) do
new_jobs.each { |job| EventMachine::defer convert(job), callback(job) }
end
end
无可否认,这些建议是从10000英尺的高空提出的。视图,但我希望里面有一些东西可以让你入门。
https://stackoverflow.com/questions/5560233
复制相似问题