83 lines
3.3 KiB
Ruby
83 lines
3.3 KiB
Ruby
|
|
module JamRuby
|
||
|
|
class QuickMixObserver < ActiveRecord::Observer
|
||
|
|
|
||
|
|
# if you change the this class, tests really should accompany. having alot of logic in observers is really tricky, as we do here
|
||
|
|
observe JamRuby::QuickMix
|
||
|
|
|
||
|
|
def before_validation(quick_mix)
|
||
|
|
|
||
|
|
# if we see that a part was just uploaded entirely, validate that we can find the part that was just uploaded
|
||
|
|
if quick_mix.is_part_uploading_was && !quick_mix.is_part_uploading
|
||
|
|
begin
|
||
|
|
aws_part = quick_mix.s3_manager.multiple_upload_find_part(quick_mix[:ogg_url], quick_mix.upload_id, quick_mix.next_part_to_upload - 1)
|
||
|
|
# calling size on a part that does not exist will throw an exception... that's what we want
|
||
|
|
aws_part.size
|
||
|
|
rescue SocketError => e
|
||
|
|
raise # this should cause a 500 error, which is what we want. The client will retry later on 500.
|
||
|
|
rescue Exception => e
|
||
|
|
quick_mix.errors.add(:next_part_to_upload, ValidationMessages::PART_NOT_FOUND_IN_AWS)
|
||
|
|
rescue RuntimeError => e
|
||
|
|
quick_mix.errors.add(:next_part_to_upload, ValidationMessages::PART_NOT_FOUND_IN_AWS)
|
||
|
|
rescue
|
||
|
|
quick_mix.errors.add(:next_part_to_upload, ValidationMessages::PART_NOT_FOUND_IN_AWS)
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
# if we detect that this just became fully uploaded -- if so, tell s3 to put the parts together
|
||
|
|
if quick_mix.marking_complete && !quick_mix.fully_uploaded_was && quick_mix.fully_uploaded
|
||
|
|
|
||
|
|
multipart_success = false
|
||
|
|
begin
|
||
|
|
quick_mix.s3_manager.multipart_upload_complete(quick_mix[:ogg_url], quick_mix.upload_id)
|
||
|
|
multipart_success = true
|
||
|
|
rescue SocketError => e
|
||
|
|
raise # this should cause a 500 error, which is what we want. The client will retry later.
|
||
|
|
rescue Exception => e
|
||
|
|
#quick_mix.reload
|
||
|
|
quick_mix.reset_upload
|
||
|
|
quick_mix.errors.add(:upload_id, ValidationMessages::BAD_UPLOAD)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
def after_commit(quick_mix)
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
# here we tick upload failure counts, or revert the state of the model, as needed
|
||
|
|
def after_rollback(quick_mix)
|
||
|
|
# if fully uploaded, don't increment failures
|
||
|
|
if quick_mix.fully_uploaded
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
# increment part failures if there is a part currently being uploaded
|
||
|
|
if quick_mix.is_part_uploading_was
|
||
|
|
#quick_mix.reload # we don't want anything else that the user set to get applied
|
||
|
|
quick_mix.increment_part_failures(quick_mix.part_failures_was)
|
||
|
|
if quick_mix.part_failures >= APP_CONFIG.max_track_part_upload_failures
|
||
|
|
# save upload id before we abort this bad boy
|
||
|
|
upload_id = quick_mix.upload_id
|
||
|
|
begin
|
||
|
|
quick_mix.s3_manager.multipart_upload_abort(quick_mix[:ogg_url], upload_id)
|
||
|
|
rescue => e
|
||
|
|
puts e.inspect
|
||
|
|
end
|
||
|
|
quick_mix.reset_upload
|
||
|
|
if quick_mix.upload_failures >= APP_CONFIG.max_track_upload_failures
|
||
|
|
# do anything?
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
def before_save(quick_mix)
|
||
|
|
# if we are on the 1st part, then we need to make sure we can save the upload_id
|
||
|
|
if quick_mix.next_part_to_upload == 1
|
||
|
|
quick_mix.upload_id = quick_mix.s3_manager.multipart_upload_start(quick_mix[:ogg_url])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|