Log In or Sign Up

Snippets — Tagged with 'juggernaut'

Mongrel upload progress with Juggernaut

Tags:
juggernaut, upload progress, upload, Ruby, Rails
Posted by:
Dave Naffis 10 months ago

Use Juggernaut to push upload progress messages for uploads instead of polling the app.

require 'mongrel'
require 'gem_plugin'
require 'juggernaut'

class Upload < GemPlugin::Plugin "/handlers"
  include Mongrel::HttpHandlerPlugin

  def initialize(options = {})
    @path_info      = Array(options[:path_info])
    @request_notify = true
    Mongrel.const_set :Uploads, Mongrel::UploadProgress.new
    Mongrel::Uploads.debug = true if options[:debug]
  end

  def request_begins(params)
    upload_notify(:add, params, params[Mongrel::Const::CONTENT_LENGTH].to_i)
  end

  def request_progress(params, clen, total)
    upload_notify(:mark, params, clen, total)
  end

  def process(request, response)
    upload_notify(:finish, request.params)
  end

  private
    def upload_notify(action, params, *args)
      return unless @path_info.include?(params['PATH_INFO']) &&
        params[Mongrel::Const::REQUEST_METHOD] == 'POST' &&
        upload_id = Mongrel::HttpRequest.query_parse(params['QUERY_STRING'])['upload_id']
      Mongrel::Uploads.send(action, upload_id, *args) 
    end
end

class Mongrel::UploadProgress
  attr_accessor :debug
  def initialize
  end

  def add(upid, size)
    Juggernaut.send_to(upid, "UploadProgress.update(#{size}, 0);")
    puts "#{upid}: Added" if @debug
  end

  def mark(upid, len, size)
    Juggernaut.send_to(upid, "UploadProgress.update(#{size}, #{size - len});")
    puts "#{upid}: Marking" if @debug
  end

  def finish(upid)
    Juggernaut.send_to(upid, "UploadProgress.finish();")
    puts "#{upid}: Finished" if @debug
  end  
end