在Ruby中长时间睡眠

时间:2016-08-03 13:57:10

标签: ruby sinatra

我有一个相当大的Sinatra应用程序(约4k行),其中一部分涉及生成报告供用户下载。

即使重新启动了网络服务器,我希望在这么多天后自动删除报告。我没有在服务器及其Windows上进行守护进程,否则我只会抛出一些cron。

这种事情通常是怎么做的?

我正在考虑类似下面的内容,但在服务器重启后它不会持续存在。

report_filename = "asdasdsad.pdf"
generate report(report_filename)
Thread.new {
  sleep((60*60*24) * 7) # wait 7 days
  File.delete(report_filename)
}

3 个答案:

答案 0 :(得分:3)

  

这种事情通常是怎么做的?

如果系统上没有cron或类似的调度程序,有几种方法。

  1. 一个消息服务器,例如RabbitMQ,您可以在其上放置一些消息,该消息具有某种属性,可以防止消息在经过一定时间后被处理和消耗。

  2. resque

  3. 等服务
  4. 服务器中的守护程序作业,每天检查一次报告文件夹(可能是凌晨2点或其他不那么繁忙的时间)并删除一周前创建的文件

  5. 与上面类似,守护程序作业检查列出文件名的db表,并对一周前创建的文件进行删除。

答案 1 :(得分:1)

无论

  1. 使用Windows任务计划程序(在Windows上有一个等效的cronjobs,有关详细信息,请参阅https://stackoverflow.com/a/132975/232838
  2. 每次创建新报告时,只需检查要删除的旧文件。我并不认为报告存在的问题太长了(我假设您因存储原因而想要删除旧文件)。

答案 2 :(得分:1)

通常你会使用cron或某种类型的job_job或Sidekiq作业队列。您可以使用Task Scheduler或命令行AT命令在Windows中执行cron作业。如果由于某些其他原因不能选择,您可以执行类似wp-cron的操作,它使用传入请求作为一种计时器来查看是否有任何需要运行的作业。它看起来像是:

require 'sinatra'
require 'date'

class App < Sinatra::Base
  configure do
    set :report_dir, '/path/to/reports'
    set :keep_for, 7 # days
  end

  helpers do
    def generate
      # write .pdf to settings.report_dir and return path to pdf
    end

    def cleanup
      Dir.glob(File.expand_path('*.pdf', settings.report_dir)) do |pdf|
        stat = File.lstat(pdf)
        File.unlink(pdf) if stat.file? and Date.today - stat.ctime.to_date > settings.keep_for
      end
    rescue Errno::ENOENT
      # another thread is working
    end
  end

  post '/generate_report' do
    send_file generate
  end

  after do
    Thread.new { cleanup } if rand < 0.01 # 1% of requests trigger cleanup
  end
end

这显然是一个简单的例子,可以帮助您入门。如果您担心多个清理线程同时运行并相互干扰,您可能会考虑使用互斥锁,并且捕获ENOENT会变得昂贵。