1

私は Sinatra と Web のプログラミングは初めてなので、使用されている用語の一部が正しくない場合があります。ともかく...

.txt を行ごとに配列に読み込むアプリがあり、index.html.erb をロードすると、行の 1 つがランダムに表示されます。コンテンツを直接配列に入れるのではなく、テキスト ファイルに入れることで、さらにデータを追加する必要がある場合に簡単に更新してから、配列に直接追加してアプリを再デプロイできるようにします。私の懸念は、ページをロードするたびに配列を再作成してファイルを再読み込みするかどうかです。そのようなことがサーバー側でどのように機能するのか、またはそれを確認する方法が正確にはわかりません。配列を作成するコードは次のとおりです。

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

そして私のルート:

get '/' do
  @way = @ways.sample

  erb :index
end

これが可能な限り効率的であることを確認する方法はありますか? それとも、まったく別の方法で行う必要がありますか? Chrome 開発ツールによると、ページの読み込みごとに最大 800b 転送されます。

4

1 に答える 1

4

ここに書いたことは、実際にリクエストごとにファイルを配列に読み込みます。

ヒント: で短く、速くすることができます@ways = File.readlines('ways.txt')

この配列をキャッシュしたい場合は、アプリの起動時に定数としてキャッシュできます。例:

WAYS = File.readlines('ways.txt').map(&:chomp)
get "/" do
  @way = WAYS.sample
  erb :index
end

ただし、テキスト ファイルを編集した場合は、サーバーを終了して再起動する必要があります。それを避けたい場合は、beforeアクションでファイルの変更時間を確認し、内容が変更された場合にのみ配列 ( replaceit ) を更新できます。

この最後の提案についてサポートが必要な場合は、お知らせください。必要に応じて編集できます。


編集:定数を使用してデータを保存し、ファイルが変更された場合にのみリロードする1つの方法を次に示します。

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
于 2012-05-23T21:26:17.397 に答える