2017-06-29 199 views
1

我在我的Symfony应用程序中使用视频转换服务。我的问题是我需要知道视频转换何时完成。流程是:我触发视频转换服务,当视频成功转换时,视频服务将视频状态更新为“转换”。如果失败,则状态为'失败'。在设置视频后,我需要继续检查视频状态。PHP知道什么时候服务完成转换

public function setVideo(Post $post, Video $video){ 

    if($video->getStatus() != 'ready_for_conversion'){ 
     throw new ApiException('video cannot be processed'); 
    }else{ 
     $videoService = $this->container->get('app.video_service'); 
     $videoService->submitJob($video); 
     $converting = true; 
     while ($converting) { 
      $status = $video->getStatus(); 
      if($status == Video::STATUS_CONVERTED) { 
       break; 
      }elseif ($status == Video::STATUS_FAILED){ 
       throw new ApiException('video failed'); 
      } 
     } 

     $post->setVideo($video); 
    } 
} 

当我运行这段代码,我得到

php.CRITICAL: Fatal Error: Maximum execution time of 30 seconds exceeded

即使视频服务一段时间后,成功更新的状态。

+1

看起来你的视频转换超过30秒。试试'set_time_limit(600);'如果它适合你 –

+0

这是利用自定义事件的一个很好的例子。您可以在转换完成后分派事件并在事件侦听器中更新您的实体。你可以发布你的转换器的来源或至少部分吗? – lordrhodos

回答

2

不知道更多关于您的应用程序的体系结构您的问题很难回答。我将假设您上传的视频需要一些时间才能完成处理。看起来像一个安全的赌注,因为视频是计算昂贵的。这就是你从代码中看到的那些代码。基本上处理视频需要30秒以上的时间,这并不奇怪。

要解决此问题,您需要重新考虑您的解决方案。最好的办法就是回头考虑你的目标。如果您的代码中的Post对象是某种类型的文章或博客文章,并且您试图在实际准备好之前阻止显示或使用视频,那么我建议您让该帖子关联该视频并移动该视频检查你的逻辑是模型。您可以在该情况下执行以下操作:

class Post 
{ 
    ... 
    public function isVideoAvailable() 
    { 
     return isset($this->video) && Video::STATUS_CONVERTED === $this->getVideo()->getStatus(); 
    } 
} 

然后在显示或在API响应中将其包装到视图模板中。这里有一个树枝例如:

{% if post.isVideoAvailable() %} 
<div class="video"> 
    <!-- put video embed code here --> 
</div> 
{% endif %} 

如果你有很好的理由,以防止视频被关联到Post。那么你可能需要把它分解成几个控制器动作。一个接受视频并开始处理,另一个接受轮询以查看它何时完成,以及最后一个关联视频(将最后两个视频组合起来,因为它不是SRP,所以对我来说似乎很麻烦,但是您可能有一个这也是很好的理由)。

还有其他的选择,如使用网络套接字或HTTP流,但这很复杂,在这里解释。

简而言之,对于长时间运行的进程使用任何Web服务端点都是不好的。这样做有一些其他性能问题会在某个时候出现,所以不要这样做。

相关问题