【发布时间】:2020-05-21 13:57:39
【问题描述】:
我需要非常频繁地执行 Symfony 命令(比如每 5-10 秒),但我的运行时环境将 cron 触发的最短时间限制为 1 分钟。所以,我想出了一个非常讨厌的解决方案,看起来像这样。我已经创建了AbstractRepetitiveCommand 类,然后我对其进行了扩展,提供了workToExecute 方法的实现。
abstract class AbstractRepetitiveCommand extends Command
{
protected int $overallMinutes = 1;
protected int $timesPerMinute = 60;
protected function execute(InputInterface $input, OutputInterface $output)
{
$startTime = microtime(true);
while (microtime(true) < $startTime + 60 * $this->overallMinutes - 60 / $this->timesPerMinute) {
if (isset($last) && microtime(true) < $last + 60 / $this->timesPerMinute) {
continue;
}
$last = microtime(true);
$this->workToExecute($input, $output);
}
}
protected function workToExecute(InputInterface $input, OutputInterface $output)
{
return;
}
}
class DoChecksCommand extends AbstractRepetitiveCommand
{
protected int $overallMinutes = 5;
protected int $timePerMinute = 4;
protected static $defaultName = 'checks:do';
/**
* @var InvestmentCheckerService
*/
private InvestmentCheckerService $checkerService;
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $entityManager;
public function __construct(InvestmentCheckerService $checkerService, EntityManagerInterface $entityManager)
{
parent::__construct('DoChecks');
$this->checkerService = $checkerService;
$this->entityManager = $entityManager;
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @throws \Exception
*/
protected function workToExecute(InputInterface $input, OutputInterface $output)
{
/** @var ArrayCollection | Pair[] $pairs */
$pairs = $this->entityManager->getRepository(Pair::class)->findAll();
foreach ($pairs as $pair) {
$this->checkerService->processChecks($pair);
$this->entityManager->persist($pair);
$this->entityManager->flush();
}
}
}
这种方法有两个问题:
- 当 2 个此类命令同时运行时,它们不会 识别对方通过flush所做的更改。有没有办法 刷新连接,因此每次运行都会从中获取数据 数据库?
- 这个解决方案总体上真的很难看。我大概是 过度思考/过于复杂,所以请告知您是否看到任何 更好地实现我想要实现的目标。
现在我尝试在每个循环开始时使用EntityManager 的clear() 方法,但它没有改变任何东西。
我想过关闭连接,但后来我没有看到关闭后重新连接的任何简单方法。
感谢您的帮助。
【问题讨论】:
标签: command-line doctrine-orm symfony4 cron-task