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



319
320
321
322
# File 'lib/action_controller/upload_progress.rb', line 319

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

Instance Attribute Details

#last_update_timeObject (readonly)

The last time the upload history was updated



310
311
312
# File 'lib/action_controller/upload_progress.rb', line 310

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.



316
317
318
# File 'lib/action_controller/upload_progress.rb', line 316

def message
  @message
end

#received_bytesObject (readonly)

Number bytes received from the multipart post



304
305
306
# File 'lib/action_controller/upload_progress.rb', line 304

def received_bytes
  @received_bytes
end

#total_bytesObject (readonly)

Total number of bytes expected from the mutlipart post



307
308
309
# File 'lib/action_controller/upload_progress.rb', line 307

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



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

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



337
338
339
# File 'lib/action_controller/upload_progress.rb', line 337

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



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

def elapsed_seconds
  @last_update_time
end

#finished?Boolean

Returns true if there are bytes pending otherwise returns false

Returns:

  • (Boolean)


400
401
402
# File 'lib/action_controller/upload_progress.rb', line 400

def finished?
  remaining_bytes <= 0
end

#remaining_bytesObject

Number of bytes left for this upload



332
333
334
# File 'lib/action_controller/upload_progress.rb', line 332

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



395
396
397
# File 'lib/action_controller/upload_progress.rb', line 395

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



326
327
328
329
# File 'lib/action_controller/upload_progress.rb', line 326

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)


411
412
413
# File 'lib/action_controller/upload_progress.rb', line 411

def stalled?
  @stalled
end

#started?Boolean

Returns true if some bytes have been received

Returns:

  • (Boolean)


405
406
407
# File 'lib/action_controller/upload_progress.rb', line 405

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.



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/action_controller/upload_progress.rb', line 347

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