Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在Sinatra中缓存文本文件内容_Ruby_Caching_Sinatra - Fatal编程技术网

Ruby 在Sinatra中缓存文本文件内容

Ruby 在Sinatra中缓存文本文件内容,ruby,caching,sinatra,Ruby,Caching,Sinatra,我不熟悉Sinatra和网络编程,所以使用的一些术语可能不太正确。无论如何 我有一个应用程序,它将.txt逐行读取到数组中,然后当你加载index.html.erb时,它会随机显示其中一行。我把内容放在一个文本文件中,而不是直接放在一个数组中,这样如果我需要添加更多的数据,那么更新就更容易了,然后直接添加到数组并重新部署应用程序。我关心的是,它是否正在重新创建数组,并在每次加载页面时重新读取文件。我不知道这种东西在服务器端是如何工作的,也不知道如何检查它。创建数组的代码如下所示: before

我不熟悉Sinatra和网络编程,所以使用的一些术语可能不太正确。无论如何

我有一个应用程序,它将.txt逐行读取到数组中,然后当你加载index.html.erb时,它会随机显示其中一行。我把内容放在一个文本文件中,而不是直接放在一个数组中,这样如果我需要添加更多的数据,那么更新就更容易了,然后直接添加到数组并重新部署应用程序。我关心的是,它是否正在重新创建数组,并在每次加载页面时重新读取文件。我不知道这种东西在服务器端是如何工作的,也不知道如何检查它。创建数组的代码如下所示:

before do
  @ways ||= ['']
  if @ways[1].nil?
    File.open('ways.txt', 'r').each_line { |line| @ways << line }
  end
end

有没有办法确保这是尽可能有效的?还是应该完全用另一种方式?根据Chrome开发工具,它每页传输约800b的负载。

您在这里写的内容确实会在每次请求时将文件读取到一个数组中

提示:使用
@ways=File.readlines('ways.txt')

如果要缓存此阵列,可以在应用程序启动时将其作为常量进行缓存,例如:

WAYS = File.readlines('ways.txt').map(&:chomp)
get "/" do
  @way = WAYS.sample
  erb :index
end
但是,如果编辑了文本文件,则需要退出并重新启动服务器。如果您想避免这种情况,可以在
操作之前检查
中文件的修改时间,并且仅在内容发生更改时更新数组(
replace
it)

如果你需要最后一个建议的帮助,请告诉我,我可以根据需要进行编辑


编辑:这里有一种方法可以使用常量保存数据并仅在文件更改时重新加载:

WAYS = { file:'ways.txt', all:[] }
before do
  if WAYS[:updated] != (mtime=File.mtime(WAYS[:file]))
    WAYS[:all].replace File.readlines(WAYS[:file]).map(&:chomp)
    WAYS[:updated] = mtime
  end
end
get "/" do
  @way = WAYS[:all].sample
  erb :index
end
这对于检查每个请求的文件修改时间来说有点过分,但是对于负载最重或速度最慢的磁盘以外的所有磁盘,性能都应该良好

另一种解决方案是启动线程,每隔几分钟强制检查/更新阵列,例如

require 'sinatra'

WAYS = { file:'ways.txt', all:[] }
Thread.new do
  loop do
    if WAYS[:updated] != (mtime= File.mtime(WAYS[:file]))
      WAYS[:all].replace File.readlines(WAYS[:file]).map(&:chomp)
      WAYS[:updated] = mtime
    end
    sleep 5 # seconds
  end
end

get '/' do
  WAYS[:all].sample
end

您在这里所写的内容确实会在每次请求时将文件读入一个数组

提示:使用
@ways=File.readlines('ways.txt')

如果要缓存此阵列,可以在应用程序启动时将其作为常量进行缓存,例如:

WAYS = File.readlines('ways.txt').map(&:chomp)
get "/" do
  @way = WAYS.sample
  erb :index
end
但是,如果编辑了文本文件,则需要退出并重新启动服务器。如果您想避免这种情况,可以在
操作之前检查
中文件的修改时间,并且仅在内容发生更改时更新数组(
replace
it)

如果你需要最后一个建议的帮助,请告诉我,我可以根据需要进行编辑


编辑:这里有一种方法可以使用常量保存数据并仅在文件更改时重新加载:

WAYS = { file:'ways.txt', all:[] }
before do
  if WAYS[:updated] != (mtime=File.mtime(WAYS[:file]))
    WAYS[:all].replace File.readlines(WAYS[:file]).map(&:chomp)
    WAYS[:updated] = mtime
  end
end
get "/" do
  @way = WAYS[:all].sample
  erb :index
end
这对于检查每个请求的文件修改时间来说有点过分,但是对于负载最重或速度最慢的磁盘以外的所有磁盘,性能都应该良好

另一种解决方案是启动线程,每隔几分钟强制检查/更新阵列,例如

require 'sinatra'

WAYS = { file:'ways.txt', all:[] }
Thread.new do
  loop do
    if WAYS[:updated] != (mtime= File.mtime(WAYS[:file]))
      WAYS[:all].replace File.readlines(WAYS[:file]).map(&:chomp)
      WAYS[:updated] = mtime
    end
    sleep 5 # seconds
  end
end

get '/' do
  WAYS[:all].sample
end

提示:要获取随机数组元素,请使用
@ways.sample
。提示:要获取随机数组元素,请使用
@ways.sample
。我理解您的意思,但如果您能充实一下,我将不胜感激。这太棒了!你给了我很多东西要读。非常感谢!这是完全实用的。我有一个web应用程序,它使用线程(a)一次睡眠5分钟(在发送排队的电子邮件之间)和(b)一次睡眠24小时(使用每天一次的快照更新数据库中的非规范化统计表)。@thekungfuman No,实例变量特定于一个请求;您需要一个跨请求soops持久化的数据结构!我打错了。固定的。我对答案进行了编辑,以包含一个在本地适用的完整独立示例(已测试)。我理解您的意思,但如果您能充实一下,我将不胜感激。这太棒了!你给了我很多东西要读。非常感谢!这是完全实用的。我有一个web应用程序,它使用线程(a)一次睡眠5分钟(在发送排队的电子邮件之间)和(b)一次睡眠24小时(使用每天一次的快照更新数据库中的非规范化统计表)。@thekungfuman No,实例变量特定于一个请求;您需要一个跨请求soops持久化的数据结构!我打错了。固定的。我对答案进行了编辑,以包含一个在本地适用的完整独立示例(已测试)。