Class: ActionController::UploadProgress::Progress

Inherits:
Object
  • Object
show all
Defined in:
lib/action_controller/upload_progress.rb

Overview

THIS IS AN EXPERIMENTAL FEATURE

Which means that it doesn't yet work on all systems. We're still working on full compatibility. It's thus not advised to use this unless you've verified it to work fully on all the systems that is a part of your environment. Consider this an extended preview.

Upload Progress abstracts the progress of an upload. It's used by the multipart progress IO that keeps track of the upload progress and creating the application depends on. It contians methods to update the progress during an upload and read the statistics such as received_bytes, total_bytes, completed_percent, bitrate, and remaining_seconds

You can get the current Progress object by calling upload_progress instance method in your controller or view.

Constant Summary collapse

MIN_SAMPLE_TIME =

Number of seconds between bitrate samples. Updates that occur more frequently than MIN_SAMPLE_TIME will not be queued until this time passes. This behavior gives a good balance of accuracy and load for both fast and slow transfers.

0.150
MIN_STALL_TIME =

Number of seconds between updates before giving up to try and calculate bitrate anymore

10.0
MAX_SAMPLES =

Number of samples used to calculate bitrate

20

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(total) ⇒ Progress

Create a new Progress object passing the expected number of bytes to receive


371
372
373
374
# File 'lib/action_controller/upload_progress.rb', line 371

def initialize(total)
  @total_bytes = total
  reset!
end

Instance Attribute Details

#last_update_timeObject (readonly)

The last time the upload history was updated


362
363
364
# File 'lib/action_controller/upload_progress.rb', line 362

def last_update_time
  @last_update_time
end

#messageObject

A message you can set from your controller or view to be rendered in the upload_status_text helper method. If you set a messagein a controller then call session.update to make that message available to your upload_status action.


368
369
370
# File 'lib/action_controller/upload_progress.rb', line 368

def message
  @message
end

#received_bytesObject (readonly)

Number bytes received from the multipart post


356
357
358
# File 'lib/action_controller/upload_progress.rb', line 356

def received_bytes
  @received_bytes
end

#total_bytesObject (readonly)

Total number of bytes expected from the mutlipart post


359
360
361
# File 'lib/action_controller/upload_progress.rb', line 359

def total_bytes
  @total_bytes
end

Instance Method Details

#bitrateObject

Calculates the bitrate in bytes/second. If the transfer is stalled or just started, the bitrate will be 0


435
436
437
438
# File 'lib/action_controller/upload_progress.rb', line 435

def bitrate
  history_bytes, history_time = @history.transpose.map { |vals| vals.inject { |sum, v| sum + v } } 
  history_bytes / history_time rescue 0
end

#completed_percentObject

Completed percent in integer form from 0..100


389
390
391
# File 'lib/action_controller/upload_progress.rb', line 389

def completed_percent
  (@received_bytes * 100 / @total_bytes).to_i rescue 0
end

#elapsed_secondsObject

Number of seconds elapsed since the start of the upload


441
442
443
# File 'lib/action_controller/upload_progress.rb', line 441

def elapsed_seconds
  @last_update_time
end

#finished?Boolean

Returns true if there are bytes pending otherwise returns false

Returns:

  • (Boolean)

452
453
454
# File 'lib/action_controller/upload_progress.rb', line 452

def finished?
  remaining_bytes <= 0
end

#remaining_bytesObject

Number of bytes left for this upload


384
385
386
# File 'lib/action_controller/upload_progress.rb', line 384

def remaining_bytes
  @total_bytes - @received_bytes
end

#remaining_secondsObject

Calculate the seconds remaining based on the current bitrate. Returns O seconds if stalled or if no bytes have been received


447
448
449
# File 'lib/action_controller/upload_progress.rb', line 447

def remaining_seconds
  remaining_bytes / bitrate rescue 0
end

#reset!Object

Resets the received_bytes, last_update_time, message and bitrate, but but maintains the total expected bytes


378
379
380
381
# File 'lib/action_controller/upload_progress.rb', line 378

def reset!
  @received_bytes, @last_update_time, @stalled, @message = 0, 0, false, ''
  reset_history
end

#stalled?Boolean

Returns true if there has been a delay in receiving bytes. The delay is set by the constant MIN_STALL_TIME

Returns:

  • (Boolean)

463
464
465
# File 'lib/action_controller/upload_progress.rb', line 463

def stalled?
  @stalled
end

#started?Boolean

Returns true if some bytes have been received

Returns:

  • (Boolean)

457
458
459
# File 'lib/action_controller/upload_progress.rb', line 457

def started?
  @received_bytes > 0
end

#update!(bytes, elapsed_seconds) ⇒ Object

Updates this UploadProgress object with the number of bytes received since last update time and the absolute number of seconds since the beginning of the upload.

This method is used by the MultipartProgress module and should not be called directly.


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/action_controller/upload_progress.rb', line 399

def update!(bytes, elapsed_seconds)#:nodoc:
  if @received_bytes + bytes > @total_bytes
    #warn "Progress#update received bytes exceeds expected bytes"
    bytes = @total_bytes - @received_bytes
  end

  @received_bytes += bytes

  # Age is the duration of time since the last update to the history
  age = elapsed_seconds - @last_update_time

  # Record the bytes received in the first element of the history
  # in case the sample rate is exceeded and we shouldn't record at this
  # time
  @history.first[0] += bytes
  @history.first[1] += age

  history_age = @history.first[1]

  @history.pop while @history.size > MAX_SAMPLES
  @history.unshift([0,0]) if history_age > MIN_SAMPLE_TIME

  if history_age > MIN_STALL_TIME
    @stalled = true
    reset_history 
  else
    @stalled = false
  end

  @last_update_time = elapsed_seconds
  
  self
end