我有一条命令需要很长时间才能运行(它会生成一个大文件)。
我想使用一个控制器在后台启动它,而不必等待其执行结束以呈现视图。
可能吗?如果是,怎么办?
我虽然Process类会很有用,但是文档说:
如果在子进程有机会完成之前发送响应,则服务器进程将被终止(取决于您的操作系统)。这意味着您的任务将立即停止。运行异步进程与运行在其父进程中幸存的进程不同。
我使用Messenger组件(如注释中的@msg)解决了我的问题。
为此,我必须:
composer require symfony/messenger
bin/console messenger:consume -vv
处理消息这是我的代码:
我使用它在视图中显示是否正在生成文件,并在文件生成完成后让用户下载文件
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\MyLogForTheBigFileRepository")
*/
class MyLogForTheBigFile
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="datetime")
*/
private $generationDateStart;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $generationDateEnd;
/**
* @ORM\Column(type="string", length=200, nullable=true)
*/
private $filename;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
private $generator;
public function __construct() { }
// getters and setters for the attributes
// ...
// ...
}
我收到表单提交并发送一条消息,该消息将运行文件生成
/**
* @return views
* @param Request $request The request.
* @Route("/generate/big-file", name="generate_big_file")
*/
public function generateBigFileAction(
Request $request,
MessageBusInterface $messageBus,
MyFileService $myFileService
)
{
// Entity manager
$em = $this->getDoctrine()->getManager();
// Creating an empty Form Data Object
$myFormOptionsFDO = new MyFormOptionsFDO();
// Form creation
$myForm = $this->createForm(
MyFormType::class,
$myFormOptionsFDO
);
$myForm->handleRequest($request);
// Submit
if ($myForm->isSubmitted() && $myForm->isValid())
{
$myOption = $myFormOptionsFDO->getOption();
// Creating the database log using a custom entity
$myFileGenerationDate = new \DateTime();
$myLogForTheBigFile = new MyLogForTheBigFile();
$myLogForTheBigFile->setGenerationDateStart($myFileGenerationDate);
$myLogForTheBigFile->setGenerator($this->getUser());
$myLogForTheBigFile->setOption($myOption);
// Save that the file is being generated using the custom entity
$em->persist($myLogForTheBigFile);
$em->flush();
$messageBus->dispatch(
new GenerateBigFileMessage(
$myLogForTheBigFile->getId(),
$this->getUser()->getId()
));
$this->addFlash(
'success', 'Big file generation started...'
);
return $this->redirectToRoute('bigfiles_list');
}
return $this->render('Files/generate-big-file.html.twig', [
'form' => $myForm->createView(),
]);
}
用于将数据传递给服务
namespace App\Message;
class GenerateBigFileMessage
{
private $myLogForTheBigFileId;
private $userId;
public function __construct(int $myLogForTheBigFileId, int $userId)
{
$this->myLogForTheBigFileId = $myLogForTheBigFileId;
$this->userId = $userId;
}
public function getMyLogForTheBigFileId(): int
{
return $this->myLogForTheBigFileId;
}
public function getUserId(): int
{
return $this->userId;
}
}
处理消息并运行服务
namespace App\MessageHandler;
use App\Service\MyFileService;
use App\Message\GenerateBigFileMessage;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class GenerateBigFileMessageHandler implements MessageHandlerInterface
{
private $myFileService;
public function __construct(MyFileService $myFileService)
{
$this->myFileService = $myFileService;
}
public function __invoke(GenerateBigFileMessage $generateBigFileMessage)
{
$myLogForTheBigFileId = $generateBigFileMessage->getMyLogForTheBigFileId();
$userId = $generateBigFileMessage->getUserId();
$this->myFileService->generateBigFile($myLogForTheBigFileId, $userId);
}
}
生成大文件并更新记录器
public function generateBigFile($myLogForTheBigFileId, $userId)
{
// Get the user asking for the generation
$user = $this->em->getRepository(User::class)->find($userId);
// Get the log object corresponding to this generation
$myLogForTheBigFile = $this->em->getRepository(MyLogForTheBigFile::class)->find($myLogForTheBigFileId);
$myOption = $myLogForTheBigFile->getOption();
// Generate the file
$fullFilename = 'my_file.pdf';
// ...
// ...
// Update the log
$myLogForTheBigFile->setGenerationDateEnd(new \DateTime());
$myLogForTheBigFile->setFilename($fullFilename);
$this->em->persist($myLogForTheBigFile);
$this->em->flush();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句