2010-06-22 32 views
10

Tôi đang phát triển ứng dụng Sinatra bao gồm biểu mẫu tải lên, với thanh tiến trình cho biết số lượng tải lên đã hoàn tất. Quá trình này, như mô tả của ryan dahl, như sau:Sinatra, thanh tiến trình ở dạng tải lên

HTTP tải lên thanh tiến trình đang thay obfuscated- họ thường đòi hỏi một quá trình đang chạy trên máy chủ theo dõi kích thước của tempfile rằng máy chủ HTTP đang viết đến, sau đó ở phía máy khách, cuộc gọi AJAX được thực hiện cứ mỗi vài giây với máy chủ trong khi tải lên để yêu cầu tiến trình tải lên.

Mỗi upload có một ngẫu nhiên session-id, và để theo dõi các hiệp hội tôi sử dụng một class variable trong ứng dụng của tôi (tôi biết, đó là khủng khiếp - nếu bạn đã có ý tưởng tốt hơn, xin vui lòng cho tôi biết)

configure do 
    @@assoc = {} 
end 

Tôi có một tuyến đường tải lên POSTGET một cho cuộc thăm dò AJAX. Bên trong tuyến đường POST tôi lưu liên kết của session-id, Tempfile và tổng kích thước.

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 

Trong con đường GET, tôi tính toán tỷ lệ phần trăm dựa trên kích thước hiện hành của Tempfile:

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 

Vấn đề là rằng đến khi yêu cầu POST vẫn chưa hoàn thành (ví dụ, sau khi có đọc tất cả các số Tempfile) số h.nil? trả về true, điều này thực sự không có ý nghĩa vì tôi vừa gán @@assoc[@sid] một giá trị trong tuyến đường khác.

Vì vậy, tôi thiếu gì ở đây?

EDIT: Tôi đã thử

  • set :reload, false
  • set :environment, :production
  • config { @@assoc ||= {} }
  • Tôi cũng đã cố gắng ném một db quan hệ vào nó (SQLite với DataMapper)

Không hoạt động.

+0

Dòng '@@ assoc [@sid] = {...' thiếu một '}' ở cuối. – Adrian

+0

cố định, cảm ơn :) – asymmetric

Trả lời

4

Tôi nghĩ rằng tôi có những gì vấn đề là:

tmp = params[:file][:tempfile] không trả lại cho đến khi các tập tin đã được nhận đầy đủ.

+0

đúng, bạn có tìm thấy giải pháp cho vấn đề này không? – dombesz

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

nên

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

vâng, đó là lỗi đánh máy trong câu hỏi, đó là ok trong ứng dụng thực tế. cảm ơn bạn đã báo cáo. – asymmetric

Các vấn đề liên quan