Виконання завдань cron
Завдання cron корисні для виконання завдань з технічного обслуговування. На відміну від воркерів, вони працюють за розкладом, протягом короткого періоду часу.
Очищування коментарів
Коментарі, позначені як спам або відхилені адміністратором, зберігаються в базі даних, оскільки адміністратор може захотіти оглянути їх пізніше. Але вони, ймовірно, мають бути видалені через деякий час. Мабуть, достатньо тримати їх протягом тижня після їх створення.
Створіть кілька корисних методів у репозиторії коментарів, щоб знайти відхилені коментарі, підрахувати їх і видалити:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
--- a/src/Repository/CommentRepository.php
+++ b/src/Repository/CommentRepository.php
@@ -6,6 +6,7 @@ use App\Entity\Comment;
use App\Entity\Conference;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
+use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
/**
@@ -16,6 +17,8 @@ use Doctrine\ORM\Tools\Pagination\Paginator;
*/
class CommentRepository extends ServiceEntityRepository
{
+ private const DAYS_BEFORE_REJECTED_REMOVAL = 7;
+
public const PAGINATOR_PER_PAGE = 2;
public function __construct(ManagerRegistry $registry)
@@ -23,6 +26,29 @@ class CommentRepository extends ServiceEntityRepository
parent::__construct($registry, Comment::class);
}
+ public function countOldRejected(): int
+ {
+ return $this->getOldRejectedQueryBuilder()->select('COUNT(c.id)')->getQuery()->getSingleScalarResult();
+ }
+
+ public function deleteOldRejected(): int
+ {
+ return $this->getOldRejectedQueryBuilder()->delete()->getQuery()->execute();
+ }
+
+ private function getOldRejectedQueryBuilder(): QueryBuilder
+ {
+ return $this->createQueryBuilder('c')
+ ->andWhere('c.state = :state_rejected or c.state = :state_spam')
+ ->andWhere('c.createdAt < :date')
+ ->setParameters([
+ 'state_rejected' => 'rejected',
+ 'state_spam' => 'spam',
+ 'date' => new \DateTimeImmutable(-self::DAYS_BEFORE_REJECTED_REMOVAL.' days'),
+ ])
+ ;
+ }
+
public function getCommentPaginator(Conference $conference, int $offset): Paginator
{
$query = $this->createQueryBuilder('c')
Tip
Для складніших запитів іноді корисно поглянути на згенеровані SQL-вирази (їх можна знайти в журналах і в профілювальнику для веб-запитів).
Використання констант класу, параметрів контейнера та змінних середовища
7 днів? Ми могли б вибрати інше число, можливо, 10 або 20. Це число може змінитися з часом. Ми вирішили зберегти його як константу в класі, але у нас є можливість зберегти його як параметр у контейнері, або навіть визначити його як змінну середовища.
Ось кілька правил, щоб вирішити, яку абстракцію використовувати:
- Якщо значення є чутливим (паролі, токени API, ...), використовуйте секретне сховище Symfony або Vault;
- Якщо значення є динамічним, і ви можете змінити його без повторного розгортання, використовуйте змінну середовища;
- Якщо значення може відрізнятися в різних середовищах, використовуйте параметр контейнера;
- Для всього іншого зберігайте значення в коді, наприклад, у константі класу.
Створення команди CLI
Видалення старих коментарів є ідеальним завданням для cron. Це слід робити на регулярній основі, а невелика затримка не надає жодного істотного впливу.
Створіть команду CLI з назвою app:comment:cleanup
, створивши файл src/Command/CommentCleanupCommand.php
:
Усі команди застосунку реєструються разом із вбудованими командами Symfony, і всі вони доступні за допомогою symfony console
. Оскільки кількість доступних команд може бути великою, вам слід групувати їх, використовуючи простори імен. За домовленістю, команди застосунку мають зберігатися в просторі імен app
. Додайте будь-яку кількість підпросторів імен, відокремивши їх двокрапкою (:
).
Команда отримує input (аргументи й параметри, передані команді), а ви можете використовувати output, щоб писати в консоль.
Очистьте базу даних, виконавши команду:
1
$ symfony console app:comment:cleanup
Налаштування cron у Platform.sh
Однією з приємних особливостей Platform.sh є те, що більша частина конфігурації зберігається в одному файлі: .platform.app.yaml
. Веб-контейнер, воркери й завдання cron описані разом, щоб полегшити обслуговування:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
--- a/.platform.app.yaml
+++ b/.platform.app.yaml
@@ -60,6 +60,14 @@ crons:
spec: '50 23 * * *'
cmd: if [ "$PLATFORM_BRANCH" = "main" ]; then croncape php-security-checker; fi
+ comment_cleanup:
+ # Cleanup every night at 11.50 pm (UTC).
+ spec: '50 23 * * *'
+ cmd: |
+ if [ "$PLATFORM_BRANCH" = "master" ]; then
+ croncape symfony console app:comment:cleanup
+ fi
+
workers:
messenger:
commands:
Секція crons
визначає всі завдання cron. Кожне завдання виконується за spec
графіком.
Утиліта croncape
відстежує виконання команди й відправляє електронний лист на адреси, визначені в змінній середовища MAILTO
, якщо команда повертає будь-який код виходу, відмінний від 0
.
Налаштуйте змінну середовища MAILTO
:
1
$ symfony cloud:variable:create --sensitive=1 --level=project -y --name=env:MAILTO --value=ops@example.com
Зверніть увагу, що завдання cron встановлені у всіх гілках Platform.sh. Якщо ви не хочете запускати деякі з них у не-продакшн середовищах, перевірте змінну середовища $SYMFONY_BRANCH
:
1 2 3
if [ "$PLATFORM_BRANCH" = "master" ]; then
croncape symfony app:invoices:send
fi