diff --git a/airtime_mvc/application/services/MediaService.php b/airtime_mvc/application/services/MediaService.php index e1712c92d..d5d43c9c7 100644 --- a/airtime_mvc/application/services/MediaService.php +++ b/airtime_mvc/application/services/MediaService.php @@ -133,17 +133,23 @@ class Application_Service_MediaService ->filterByDbImportStatus(CcFiles::IMPORT_STATUS_PENDING) ->filterByDbUtime($oneHourAgo, Criteria::LESS_EQUAL) ->find(); - return !empty(self::$_pendingFiles); + $pendingEpisodes = Application_Service_PodcastEpisodeService::getStuckPendingImports(); + return !empty(self::$_pendingFiles) && !empty($pendingEpisodes); } /** * Clean up stuck imports by changing their import status to Failed */ public static function clearStuckPendingImports() { - foreach(self::$_pendingFiles as $file) { + $pendingEpisodes = Application_Service_PodcastEpisodeService::getStuckPendingImports(); + foreach (self::$_pendingFiles as $file) { /** @var $file CcFiles */ $file->setDbImportStatus(CcFiles::IMPORT_STATUS_FAILED)->save(); } + foreach ($pendingEpisodes as $episode) { + /** @var $episode PodcastEpisodes */ + $episode->delete(); + } } } diff --git a/airtime_mvc/application/services/PodcastEpisodeService.php b/airtime_mvc/application/services/PodcastEpisodeService.php index 56298e467..313518744 100644 --- a/airtime_mvc/application/services/PodcastEpisodeService.php +++ b/airtime_mvc/application/services/PodcastEpisodeService.php @@ -12,6 +12,8 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir const DOWNLOAD = 'download'; + const PENDING_EPISODE_TIMEOUT_SECONDS = 3600; + /** * @var string service name to store in ThirdPartyTrackReferences database */ @@ -143,7 +145,11 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir 'callback_url' => Application_Common_HTTPHelper::getStationUrl() . '/rest/media', 'api_key' => $apiKey = $CC_CONFIG["apiKey"][0], ); - $this->_executeTask(static::$_CELERY_TASKS[self::DOWNLOAD], $data); + $task = $this->_executeTask(static::$_CELERY_TASKS[self::DOWNLOAD], $data); + // Get the created ThirdPartyTaskReference and set the episode ID so + // we can remove the placeholder if the import ends up stuck in a pending state + $ref = ThirdPartyTrackReferencesQuery::create()->findPk($task->getDbTrackReference()); + $ref->setDbForeignId($id)->save(); } /** @@ -161,6 +167,7 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir */ public function updateTrackReference($task, $episodeId, $episode, $status) { $ref = parent::updateTrackReference($task, $episodeId, $episode, $status); + $ref->setDbForeignId($episode->episodeid)->save(); $dbEpisode = PodcastEpisodesQuery::create()->findOneByDbId($episode->episodeid); try { @@ -231,6 +238,32 @@ class Application_Service_PodcastEpisodeService extends Application_Service_Thir return (int) $stationPodcast->hasEpisodeForFile($fileId); } + /** + * Find any episode placeholders that have been stuck pending (empty file ID) for over an hour + * + * @return array the episode imports stuck in pending + */ + public static function getStuckPendingImports() { + $oneHourAgo = gmdate(DEFAULT_TIMESTAMP_FORMAT, (microtime(true) - self::PENDING_EPISODE_TIMEOUT_SECONDS)); + $episodes = PodcastEpisodesQuery::create() + ->filterByDbFileId() + ->find(); + $stuckImports = array(); + foreach ($episodes as $episode) { + $ref = ThirdPartyTrackReferencesQuery::create() + ->findOneByDbForeignId(strval($episode->getDbId())); + if (!empty($ref)) { + $task = CeleryTasksQuery::create() + ->filterByDbDispatchTime($oneHourAgo, Criteria::LESS_EQUAL) + ->findOneByDbTrackReference($ref->getDbId()); + if (!empty($task)) { + array_push($stuckImports, $episode); + } + } + } + return $stuckImports; + } + /** * @param $episodeId * @return array diff --git a/airtime_mvc/application/services/ThirdPartyCeleryService.php b/airtime_mvc/application/services/ThirdPartyCeleryService.php index f1f3f709a..e84645086 100644 --- a/airtime_mvc/application/services/ThirdPartyCeleryService.php +++ b/airtime_mvc/application/services/ThirdPartyCeleryService.php @@ -20,15 +20,20 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S * @param string $taskName the name of the celery task to execute * @param array $data the data array to send as task parameters * @param int $fileId the unique identifier for the file involved in the task + * + * @return CeleryTasks the created task + * + * @throws Exception */ protected function _executeTask($taskName, $data, $fileId = null) { try { $brokerTaskId = CeleryManager::sendCeleryMessage($taskName, static::$_CELERY_EXCHANGE_NAME, $data); - $this->_createTaskReference($fileId, $brokerTaskId, $taskName); + return $this->_createTaskReference($fileId, $brokerTaskId, $taskName); } catch (Exception $e) { - Logging::info("Invalid request: " . $e->getMessage()); + Logging::error("Invalid request: " . $e->getMessage()); + throw $e; } } @@ -41,6 +46,8 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S * receive completed task messages * @param $taskName string broker task name * + * @return CeleryTasks the created task + * * @throws Exception * @throws PropelException */ @@ -54,6 +61,7 @@ abstract class Application_Service_ThirdPartyCeleryService extends Application_S $task->setDbStatus(CELERY_PENDING_STATUS); $task->setDbTrackReference($trackReferenceId); $task->save(); + return $task; } /** diff --git a/airtime_mvc/application/services/ThirdPartyService.php b/airtime_mvc/application/services/ThirdPartyService.php index 1fca386f5..61a979ea6 100644 --- a/airtime_mvc/application/services/ThirdPartyService.php +++ b/airtime_mvc/application/services/ThirdPartyService.php @@ -30,12 +30,10 @@ abstract class Application_Service_ThirdPartyService { public function createTrackReference($fileId) { // First, check if the track already has an entry in the database // If the file ID given is null, create a new reference - $ref = is_null($fileId) ? null : ThirdPartyTrackReferencesQuery::create() - ->filterByDbService(static::$_SERVICE_NAME) - ->findOneByDbFileId($fileId); - if (is_null($ref)) { - $ref = new ThirdPartyTrackReferences(); - } + $ref = is_null($fileId) ? new ThirdPartyTrackReferences() + : ThirdPartyTrackReferencesQuery::create() + ->filterByDbService(static::$_SERVICE_NAME) + ->findOneByDbFileId($fileId); $ref->setDbService(static::$_SERVICE_NAME); $ref->setDbFileId($fileId); $ref->save(); diff --git a/airtime_mvc/application/views/scripts/podcast/podcast.phtml b/airtime_mvc/application/views/scripts/podcast/podcast.phtml index d9ff7ebe8..313419914 100644 --- a/airtime_mvc/application/views/scripts/podcast/podcast.phtml +++ b/airtime_mvc/application/views/scripts/podcast/podcast.phtml @@ -1,5 +1,3 @@ - -