Sinatra具有持久变量

我的sinatra应用程序必须解析一个~60MB的XML文件。 这个文件几乎没有变化:在夜间的cron工作中,它被另一个人覆盖。

是否存在将解析后的文件作为变量保存在内存中的技巧或方法,以便我可以在传入请求中读取它,但不必为每个传入请求一遍又一遍地解析它?

一些Pseudocode来说明我的问题。

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运行时它仍然存在。 这有可能吗? 或者我需要一些存储空间?

你可以尝试:

 configure do @@nokogiri_object = parse_xml end 

然后, @@nokogiri_object将在您的请求方法中提供。 它是一个类变量而不是实例变量,但应该做你想要的。

建议的解决方案发出警告

警告:来自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 

两种选择:

  • 将解析后的文件保存到新文件中,并始终读取该文件。

您可以将文件 – serialize – 保存为具有两个键的哈希:’last-modified’和’data’。

“最后修改”值是一个日期,如果那天是今天,您将检入每个请求。 如果它不是今天,则下载,解析并存储今天日期的新文件。

‘data’值是解析的文件。

这样你只需解析一次,就像一个缓存。

  • 将解析的文件保存到NoSQL数据库,例如redis。