嗨,我试图在后台执行一个长时间运行的请求(动作)。
function actionRequest($id){
//execute very long process here in background but continue redirect
Yii::app()->user->setFlash('success', "Currently processing your request you may check it from time to time.");
$this->redirect(array('index', 'id'=>$id));
}我试图实现的是,不让用户等待来处理请求,因为这通常需要5-10分钟,并且请求通常会转到超时,即使我设置超时时间更长,也会等待5-10分钟。不是很好的用户体验。
因此,我希望立即返回到页面,通知用户他/她的请求正在处理中,而他/她仍然可以浏览,并在应用程序中执行其他操作,然后他/她可以返回该页面并查看他/她的请求是否已被处理。
我已经查看了Yii扩展背靠背,它可以工作,重定向会立即执行(某种程度上是后台请求),但是当执行其他事情时,比如在站点中导航时,它不会加载,而且似乎请求仍然存在,并且在请求完成之前我不能继续使用应用程序。
一个类似的扩展运行承诺同样的事情,但我甚至不能让它工作,它说它“触摸一个url”,就像火灾和忘记工作,但不起作用。
我也尝试过查看消息队列服务,如吉尔曼、RabbitMQ,但这是非常技术性的,我甚至无法在我的windows机器中安装Gearman,这样“耕作”服务对我就不起作用了。一些背景处理的答案包括CRON和AJAX,但听起来不太好,还有很多问题。
对于异步后台处理,还有其他解决办法吗?我真的很努力地寻找这一点,我真的不想寻找高级/复杂的解决方案,比如“把工作外包给几台机器”等等。非常感谢!
发布于 2014-10-10 15:56:56
如果您希望能够通过Yii运行异步作业,您可能别无选择,只能使用一些AJAX来异步检索作业的状态。这里有一些对我有用的高级指南。希望这能在某种程度上帮助你!
设置控制台操作
要运行后台作业,您需要使用Yii的控制台组件。在/保护区/命令下,创建一个包含actionRequest()的web控制器的副本(例如/protected/commands/BulkCommand.php)。
这将允许您在/protected文件夹中运行yiic bulk request。
请记住,如果您以前没有创建过控制台应用程序,您需要设置它的配置,就像您为web应用程序所做的那样。将/protected/config/main.php直接复制到/protected/config/ copy e.php中应该可以完成90%的工作。
自定义用于运行异步控制台作业的扩展
对我起作用的是使用两个扩展的组合:CConsole和TConsoleRunner。TConsoleRunner使用popen运行shell脚本,它在Windows和Ubuntu上对我起作用。我简单地将它的run()代码合并到CConsole中,如下所示:
public function popen($shell, $redirectOutput = '')
{
$shell = $this->resolveCommandLine($shell, false, $redirectOutput);
$ret = self::RETURN_CODE_SUCCESS;
if (!$this->displayCommands) {
ob_start();
}
if ($this->isWindows()) {
pclose(popen('start /b '.$shell, 'r'));
}
else {
pclose(popen($shell.' > /dev/null &', 'r'));
}
if (!$this->displayCommands) {
ob_end_clean();
}
return $ret;
}
protected function isWindows()
{
if(PHP_OS == 'WINNT' || PHP_OS == 'WIN32')
return true;
else
return false;
}之后,我将CConsole的runCommand()更改为:
public function runCommand($command, $args, $async = false, &$outputLines = null, $executor = 'popen')
{
...
switch ($executor) {
...
case 'popen':
return $this->popen($shell);
...
}
}运行异步作业
有了上面的设置,现在您可以使用下面的代码片段来调用我们前面创建的yiic bulk request。
$console = new CConsole();
$console->runCommand('bulk request', array(
'--arg1="argument"',
'--arg2="argument"',
'--arg3="argument"',
));您可以将其插入原始的actionRequest()中。
检查状态
不幸的是,我不知道你的批量请求是做什么样的工作。对我自己来说,我收集了一大堆文件并把它们放在一个文件夹里。我知道有多少文件是我所期望的,所以我可以很容易地创建一个控制器操作来验证到目前为止已经创建了多少个文件,并给出了一个简单的划分状态的%。
https://stackoverflow.com/questions/26269872
复制相似问题