jam-cloud/ruby/lib/jam_ruby/models/quick_mix_observer.rb

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