我有一个相当大的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)
}
答案 0 :(得分:3)
这种事情通常是怎么做的?
如果系统上没有cron或类似的调度程序,有几种方法。
一个消息服务器,例如RabbitMQ,您可以在其上放置一些消息,该消息具有某种属性,可以防止消息在经过一定时间后被处理和消耗。
服务器中的守护程序作业,每天检查一次报告文件夹(可能是凌晨2点或其他不那么繁忙的时间)并删除一周前创建的文件
与上面类似,守护程序作业检查列出文件名的db表,并对一周前创建的文件进行删除。
答案 1 :(得分:1)
无论
答案 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会变得昂贵。