Синатра, индикатор в форме загрузки - PullRequest
10 голосов
/ 22 июня 2010

Я разрабатываю приложение Sinatra, которое состоит из формы загрузки, с индикатором выполнения, показывающим, какая часть загрузки завершена.Процесс, описанный ryan dahl , выглядит следующим образом:

Индикаторы выполнения загрузки HTTP довольно запутаны - они обычно включают процесс, выполняемый на сервере, отслеживающий размериз временного файла, в который HTTP-сервер записывает данные, затем на стороне клиента каждые две секунды на сервер выполняется вызов AJAX, чтобы запросить ход загрузки.

Каждая загрузкаимеет случайный session-id, и для отслеживания ассоциации я использую class variable в своем приложении (я знаю, это ужасно - если у вас есть лучшие идеи, пожалуйста, скажите мне)

configure do
  @@assoc = {}
end

У меня есть POST маршрут для загрузки и GET маршрут для опроса AJAX.Внутри маршрута POST я сохраняю ассоциацию session-id, Tempfile и общий размер.

post '/files' do
  tmp = params[:file][:tempfile]
  # from here on, @@assoc[@sid] should have a value, even in other routes
  @@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] } 
  File.open("#{options.filesdir}/#{filename}", 'w+') do |file|
    file << tmp.read
  end
end 

На маршруте GET я вычисляю процент на основе Tempfile 's текущий размер:

get '/status/:sid' do
  h = @@assoc[params[:sid]]
  unless h.nil?
    percentage = (h[:file].size / h[:size].to_f) * 100 
    "#{percentage}%"
  else
    "0%"
  end 
end

Проблема заключается в том, что до тех пор, пока запрос POST не будет завершен (т. е. после прочтения всех Tempfile), h.nil? вернет true,что на самом деле не имеет смысла, так как я только что присвоил @@assoc[@sid] значение в другом маршруте.

Итак, что мне здесь не хватает?

РЕДАКТИРОВАТЬ: Я пытался

  • set :reload, false
  • set :environment, :production
  • config { @@assoc ||= {} }
  • Я также пытался бросить реляционныйдБ у него (SQLite с DataMapper)

Ни сработало.

Ответы [ 2 ]

4 голосов
/ 23 июня 2010

Мне кажется, я понял, в чем проблема:

tmp = params[:file][:tempfile] не возвращается, пока файл не будет получен полностью.

1 голос
/ 22 июня 2010
@@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] }

должно быть

@@assoc[params[:sid]] = { :file => tmp, :size => env['CONTENT_LENGTH'] }
...