亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在后臺執行長任務?

如何在后臺執行長任務?

PHP
嚕嚕噠 2022-09-12 10:10:36
我有一個使用Symfony 5制作的應用程序,我有一個腳本,可以將服務器上的視頻上傳到登錄的用戶頻道。這基本上是我的控制器的代碼:    /**     * Upload a video to YouTube.     *     * @Route("/upload_youtube/{id}", name="api_admin_video_upload_youtube", methods={"POST"}, requirements={"id" = "\d+"})     */    public function upload_youtube(int $id, Request $request, VideoRepository $repository, \Google_Client $googleClient): JsonResponse    {        $video = $repository->find($id);        if (!$video) {            return $this->json([], Response::HTTP_NOT_FOUND);        }        $data = json_decode(            $request->getContent(),            true        );        $googleClient->setRedirectUri($_SERVER['CLIENT_URL'] . '/admin/videos/youtube');        $googleClient->fetchAccessTokenWithAuthCode($data['code']);        $videoPath = $this->getParameter('videos_directory') . '/' . $video->getFilename();        $service = new \Google_Service_YouTube($googleClient);        $ytVideo = new \Google_Service_YouTube_Video();        $ytVideoSnippet = new \Google_Service_YouTube_VideoSnippet();        $ytVideoSnippet->setTitle($video->getTitle());        $ytVideo->setSnippet($ytVideoSnippet);        $ytVideoStatus = new \Google_Service_YouTube_VideoStatus();        $ytVideoStatus->setPrivacyStatus('private');        $ytVideo->setStatus($ytVideoStatus);        $chunkSizeBytes = 1 * 1024 * 1024;        $googleClient->setDefer(true);        $insertRequest = $service->videos->insert(            'snippet,status',            $ytVideo        );       這基本上是有效的,但問題是視頻可能非常大(10G +),所以它需要很長時間,基本上Nginx在結束之前終止,并在上傳完成之前返回“504網關超時”。無論如何,我不希望用戶在上傳頁面時必須等待頁面加載。因此,我正在尋找一種方法,而不僅僅是立即運行該腳本,而是在某種后臺線程中或以異步方式執行該腳本??刂破飨蛴脩舴祷豠,我可以告訴他正在上傳,稍后再回來檢查進度。200如何做到這一點?
查看完整描述

1 回答

?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

有很多方法可以做到這一點,但你基本上想要的是解耦動作觸發器及其執行。

只是:

  • 從控制器中刪除所有繁重的工作。您的控制器最多只應檢查客戶端提供的視頻 ID 是否存在于 .VideoRepository

  • 存在?很好,那么您需要將此“工作訂單”存儲在某個地方。

    有許多解決方案,具體取決于您已經安裝的內容,您感覺更舒適的技術等。

    為了簡單起見,假設您有一張帶有 、 和 的表,也許還有 。因此,您的控制器唯一要做的就是在此表中創建一個新記錄(也許檢查作業是否尚未“排隊”,這種詳細信息取決于您的實現)。PendingUploadsvideoIdstatuscreatedAtuserId

  • 然后返回(或 ,在這種情況下可能更合適200202)

然后,您需要編寫一個單獨的進程。

很可能是您定期執行的控制臺命令(使用最簡單的方法)cron

在每次執行時,該進程(將具有所有邏輯,并且可能還有一個)將檢查哪些作業正在等待上傳,按順序處理它們,并設置為您表示要完成的任何內容。例如,您可能必須(掛起)、(處理)和(已處理),并在腳本的每個步驟上相應地設置狀態。Google_ClientPendingUploadsRepositorystatusstatus012

具體實現此目的的詳細信息取決于您。這個問題過于寬泛和固執己見。選擇一些你已經理解的東西,讓你移動得更快。如果要將作業存儲在 Rabbit、Redis、數據庫或平面文件中,則不是特別重要。如果以 或 開頭的“使用者”。cronsupervisor

Symfony有一個現成的組件,可以讓你異步解耦這種消息傳遞(Symfony信使),這很不錯。調查它是否是你的一杯茶,盡管如果你不打算在你的應用程序中將其用于其他任何事情,我會讓它變得簡單。


查看完整回答
反對 回復 2022-09-12
  • 1 回答
  • 0 關注
  • 90 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號