@@ -91,18 +91,15 @@ def publish!
9191
9292 def upload_and_process! ( eps )
9393 Rails . logger . tagged ( "Apple::Publisher#upload_and_process!" ) do
94- eps . filter ( &:apple_needs_upload? ) . each_slice ( PUBLISH_CHUNK_LEN ) do |eps |
95- upload_media! ( eps )
94+ eps . filter ( &:apple_needs_upload? ) . each_slice ( PUBLISH_CHUNK_LEN ) do |batch |
95+ upload_media! ( batch )
9696 end
9797
98- eps . filter ( &:apple_needs_delivery? ) . each_slice ( PUBLISH_CHUNK_LEN ) do |eps |
99- process_delivery! ( eps )
98+ eps . filter ( &:apple_needs_delivery? ) . each_slice ( PUBLISH_CHUNK_LEN ) do |batch |
99+ process_delivery! ( batch )
100100 end
101101
102- eps . each_slice ( PUBLISH_CHUNK_LEN ) do |eps |
103- publish_drafting! ( eps )
104- raise_delivery_processing_errors ( eps )
105- end
102+ raise_delivery_processing_errors ( eps )
106103 end
107104 end
108105
@@ -145,9 +142,11 @@ def process_delivery!(eps)
145142 wait_for_upload_processing ( eps )
146143
147144 # Wait for the audio asset to be processed by Apple
148- # Mark episodes as delivered as they are processed
149145 wait_for_asset_state ( eps ) do |ready_eps |
150146 log_asset_wait_duration! ( ready_eps )
147+ # Publish the ready episodes
148+ publish_drafting! ( ready_eps )
149+ # Then mark them as delivered
151150 mark_as_delivered! ( ready_eps )
152151 end
153152 end
@@ -398,11 +397,47 @@ def mark_as_uploaded!(eps)
398397 end
399398 end
400399
400+ def verify_publishing_state! ( eps )
401+ # Capture initial state before polling to detect drift
402+ initial_states = eps . to_h { |ep | [ ep . feeder_id , ep . publishing_state ] }
403+
404+ poll_episodes! ( eps )
405+
406+ drifted_count = eps . count do |ep |
407+ initial_state = initial_states [ ep . feeder_id ]
408+ ( ep . publishing_state != initial_state ) . tap do |drifted |
409+ if drifted
410+ Rails . logger . warn ( "Episode publishing state found to be out of sync" , {
411+ episode_id : ep . feeder_id ,
412+ local_expected_state : initial_state ,
413+ remote_actual_state : ep . publishing_state
414+ } )
415+ end
416+ end
417+ end
418+
419+ if drifted_count . positive?
420+ raise Apple ::RetryPublishingError . new ( "Detected #{ drifted_count } episodes with publishing state drift" )
421+ end
422+
423+ true
424+ end
425+
401426 def publish_drafting! ( eps )
402427 Rails . logger . tagged ( "##{ __method__ } " ) do
403- eps = eps . select { |ep | ep . drafting? && ep . container_upload_complete? }
428+ # Guard: verify all episodes are in a consistent local and remote state
429+ verify_publishing_state! ( eps )
430+
431+ drafting_eps , non_ready_eps = eps . partition { |ep | ep . drafting? && ep . container_upload_complete? }
432+ non_ready_eps . each do |ep |
433+ Rails . logger . info ( "Skipping publish for non-ready episode" , { episode_id : ep . feeder_id ,
434+ publishing_state : ep . publishing_state ,
435+ container_upload_complete : ep . container_upload_complete? } )
436+ end
437+
438+ Rails . logger . info ( "Publishing #{ drafting_eps . length } drafting episodes." , { drafting_episode_ids : drafting_eps . map ( &:feeder_id ) } ) if drafting_eps . any?
404439
405- res = Apple ::Episode . publish ( api , show , eps )
440+ res = Apple ::Episode . publish ( api , show , drafting_eps )
406441
407442 Rails . logger . info ( "Published #{ res . length } drafting episodes." )
408443 end
0 commit comments