Ruby 红宝石长眠
我有一个相当大的Sinatra应用程序(大约4k行),其中一部分涉及生成报告供用户下载 我希望报告在这么多天后自动删除,即使Web服务器重新启动。我在服务器上没有守护进程,它是Windows,否则我会抛出一些cron 这种事情通常是怎么做的? 我在考虑下面这样的事情,但在服务器重新启动后它不会持续Ruby 红宝石长眠,ruby,sinatra,Ruby,Sinatra,我有一个相当大的Sinatra应用程序(大约4k行),其中一部分涉及生成报告供用户下载 我希望报告在这么多天后自动删除,即使Web服务器重新启动。我在服务器上没有守护进程,它是Windows,否则我会抛出一些cron 这种事情通常是怎么做的? 我在考虑下面这样的事情,但在服务器重新启动后它不会持续 report_filename = "asdasdsad.pdf" generate report(report_filename) Thread.new { sleep((60*60*24) *
report_filename = "asdasdsad.pdf"
generate report(report_filename)
Thread.new {
sleep((60*60*24) * 7) # wait 7 days
File.delete(report_filename)
}
这种事情通常是怎么做的
在系统上没有cron或类似调度器的情况下,有两种方法
通常,您会使用cron或某种作业队列,如delayed_job或Sidekiq。您可以在Windows中使用任务调度器或命令行AT命令执行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
需要“sinatra”
需要“日期”
类应用程序settings.keep_for
结束
营救错误号::enoint
#另一个线程正在工作
结束
结束
发布'/generate_report'do
发送文件生成
结束
事后
Thread.new{cleanup}如果rand<0.01#1%的请求触发清理
结束
结束
这显然是一个简单的例子,让你开始。你可能会考虑使用互斥体,如果你担心多个清理线程同时运行并互相干扰,并且捕获EnoTo变得昂贵。
通常你会使用CRON或类似DelayEdJoBooWord或SosiKiq之类的作业队列。您可以在Windows中使用任务调度器或命令行AT命令执行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
需要“sinatra”
需要“日期”
类应用程序settings.keep_for
结束
营救错误号::enoint
#另一个线程正在工作
结束
结束
发布'/generate_report'do
发送文件生成
结束
事后
Thread.new{cleanup}如果rand<0.01#1%的请求触发清理
结束
结束
这显然是一个简单的例子,让你开始。如果你担心多个清理线程同时运行和相互干扰,并且捕获EnoTo变得昂贵,你可能会考虑使用互斥。您正在询问如何执行解决方案,但问题应该是“n天后生成和删除报告的正确方法是什么”。这不应该在Sinatra内部完成,而是让它服务于报告生成器的输出。如果报告运行速度很快,则以内联方式执行。如果他们需要一段时间,那么在西纳特拉以外的某个老太婆那里做。无论哪种方式,都要编写一些每隔一段时间运行的内容,以清除Sinatra之外的旧文件。通过查看磁盘上的时间戳确定报告期限,该时间戳在重新启动服务器后仍然有效。您的问题是XY问题。哟