Class: CloudflareUpdatesWorker

Inherits:
Object
  • Object
show all
Includes:
Sidekiq::Worker, Workers::StatusBroadcastable
Defined in:
app/workers/cloudflare_updates_worker.rb

Constant Summary collapse

MAX_WAIT_TIME =

Maximum time to wait for downloads (30 minutes)

30.minutes
CHECK_INTERVAL =

Check status every 30 seconds

30.seconds
MAX_CHECKS =

Maximum number of checks

(MAX_WAIT_TIME / CHECK_INTERVAL).to_i

Instance Attribute Summary

Attributes included from Workers::StatusBroadcastable

#broadcast_status_updates

Instance Method Summary collapse

Methods included from Workers::StatusBroadcastable::Overrides

#at, #store, #total

Instance Method Details

#perform(video_id, options = {}) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'app/workers/cloudflare_updates_worker.rb', line 14

def perform(video_id, options = {})
  @video = Video.find(video_id)
  @options = options.symbolize_keys
  @redirect_path = @options[:redirect_path] || "#{CRM_URL}/videos/#{@video.id}"
  @start_time = Time.current

  # Set initial status
  total(100)
  at(0, 'Starting Cloudflare updates...')

  begin
    # Step 1: Refresh Cloudflare data to get latest metadata (including duration and download status)
    at(5, 'Refreshing Cloudflare data...')
    @video.refresh_cloudflare_data
    at(10, 'Cloudflare data refreshed')

    # Step 2: Extract poster frame at 5 seconds for better visual representation
    at(12, 'Extracting poster frame at 5 seconds...')
    @video.extract_poster_at_timestamp(5.0)
    at(15, 'Poster extraction completed')

    # Step 3: Handle default video download action
    case @options[:default_download_action]
    when 'enable'
      at(20, 'Enabling default video download...')
      raise 'Failed to enable default video download' unless @video.enable_mp4_download('default')

      at(25, 'Default video download enabled, waiting for processing...')
      wait_for_download_ready('default', 25, 45) # 25-45% range
    when 'disable'
      at(20, 'Deleting default video download...')
      @video.delete_mp4_download('default')
      at(45, 'Default video download deleted')
    else
      at(45, 'Skipping default video download...')
    end

    # Step 4: Handle audio download action
    case @options[:audio_download_action]
    when 'enable'
      at(50, 'Enabling audio download...')
      raise 'Failed to enable audio download' unless @video.enable_mp4_download('audio')

      at(55, 'Audio download enabled, waiting for processing...')
      wait_for_download_ready('audio', 55, 75) # 55-75% range
    when 'disable'
      at(50, 'Deleting audio download...')
      @video.delete_mp4_download('audio')
      at(75, 'Audio download deleted')
    else
      at(75, 'Skipping audio download...')
    end

    # Step 5: Handle VTT captions actions
    caption_service = CloudflareVttService.new(@video)
    performed_any_caption_action = false

    # Handle English captions action
    case @options[:vtt_captions_en_action]
    when 'enable'
      at(80, 'Uploading English VTT captions to Cloudflare...')
      caption_service.upload_vtt_captions_en
      at(82, 'English VTT captions uploaded successfully')
      performed_any_caption_action = true
    when 'disable'
      at(80, 'Deleting English VTT captions from Cloudflare...')
      caption_service.delete_vtt_captions('en')
      at(82, 'English VTT captions deleted successfully')
      performed_any_caption_action = true
    end

    # Handle translated captions for each available locale
    current_progress = 82
    progress_per_locale = 3.0 / VideoProcessing::VideoTranslationService::SUPPORTED_LOCALES.keys.length

    VideoProcessing::VideoTranslationService::SUPPORTED_LOCALES.each do |locale, info|
      action_key = :"vtt_captions_#{locale.underscore}_action"
      action = @options[action_key]

      case action
      when 'enable'
        at(current_progress.round, "Uploading #{info[:name]} VTT captions to Cloudflare...")
        caption_service.upload_vtt_captions_translated(locale)
        at((current_progress + progress_per_locale).round, "#{info[:name]} VTT captions uploaded successfully")
        performed_any_caption_action = true
      when 'disable'
        at(current_progress.round, "Deleting #{info[:name]} VTT captions from Cloudflare...")
        caption_service.delete_vtt_captions(locale)
        at((current_progress + progress_per_locale).round, "#{info[:name]} VTT captions deleted successfully")
        performed_any_caption_action = true
      end

      current_progress += progress_per_locale
    end

    at(85, 'Skipping VTT captions...') unless performed_any_caption_action

    # Step 6: Refresh Cloudflare data again to get updated download status
    at(90, 'Performing final status refresh...')
    @video.refresh_cloudflare_data
    at(95, 'All updates verified!')

    # Complete
    store status: 'completed'
    at(100, 'Cloudflare updates completed successfully!')
    store redirect_to: @redirect_path
  rescue StandardError => e
    error_message = e.message
    Rails.logger.error "Cloudflare updates failed for video #{@video.id}: #{error_message}"
    Rails.logger.error e.backtrace.join("\n")

    # Store failure status and error message for the job progress page
    store status: 'failed'
    store error_message: error_message
    store redirect_to: @redirect_path

    # Report to AppSignal
    ErrorReporting.error(e, source: :background, video_id: @video.id)
  end
end