我的sinatra应用程序必须解析一个~60MB的XML文件。这个文件几乎没有变化:在夜间的cron工作中,它被另一个人覆盖。
是否存在将解析后的文件作为变量保存在内存中的技巧或方法,以便我可以在传入的请求中读取它,但不必为每个传入的请求一遍又一遍地解析它?
一些伪代码来说明我的问题。
get '/projects/:id'
return @nokigiri_object.search("//projects/project[@id=#{params[:id]}]/name/text()")
end
post '/projects/update'
if params[:token] == "s3cr3t"
@nokogiri_object = reparse_the_xml_file
end
end
我需要知道的是,如何创建这样一个@nokogiri_object,以便在Sinatra运行时它仍然存在。这有可能吗?或者我需要一些存储空间吗?
答案 0 :(得分:9)
你可以尝试:
configure do
@@nokogiri_object = parse_xml
end
然后@@nokogiri_object
将在您的请求方法中提供。它是一个类变量而不是实例变量,但应该做你想要的。
答案 1 :(得分:8)
建议的解决方案发出警告
警告:来自toplevel的类变量访问
您可以使用类方法访问类变量,警告将消失
require 'sinatra'
class Cache
@@count = 0
def self.init()
@@count = 0
end
def self.increment()
@@count = @@count + 1
end
def self.count()
return @@count
end
end
configure do
Cache::init()
end
get '/' do
if Cache::count() == 0
Cache::increment()
"First time"
else
Cache::increment()
"Another time #{Cache::count()}"
end
end
答案 2 :(得分:0)
两个选项:
您可以保存文件 - 序列化 - 带有两个键的哈希:'last-modified'和'data'。
“最后修改”值是一个日期,如果当天是今天,您会检入每个请求。如果它不是今天,则下载,解析并存储今天日期的新文件。
'data'值是已解析的文件。
这样你只需解析一次,就像缓存一样。