Sinatra具有持久变量

时间:2011-06-22 17:05:22

标签: ruby sinatra scope

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

3 个答案:

答案 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'值是已解析的文件。

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

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