Так как в условиях задачи ничего не сказано о необходимом уровне производительности, то было принято решение реализовать самый простой вариант без параллельной обработки.
Этот вариант очевиден, всем понятен и может служить отправной точкой для дальнейших оптимизаций.
При ужесточении требований к производительности необходимо доработать решение:
- Подумать над возможностью проверять email в момент регистрации, чтобы у пользователя была возможность исправить его.
- Внедрить систему очередей заданий (очередь на проверку, очередь на отправку email-писем) с множеством worker'ов.
- Вынести наиболее ресурсоемкие вычисления (check_email) в отдельный микросервис/программу на более подходящем стеке (например, Golang).
В него вынесены все параметры подключения к БД, в данном решении используется PostgreSQL.
Передача параметров подключения в данном решении выполняется через ENV-переменные. Альтернативные варианты передачи конфигурационных параметров:
- параметры командной строки;
- общий конфигурационный файл (PHP, JSON, YAML);
- внешние системы (HashiCorp Vault, Consul и т.д).
В него вынесена функция для логирования возникающих ошибок.
В данном решении реализовано простейшее логирование с остановкой работы при любой ошибке. В production-окружении такое решение не подойдет, его необходимо доработать:
- Рассмотреть возможность не завершать скрипт при любой ошибке, какие-то ошибки могут быть обработаны.
- Вывод ошибок в json-формате для удобства их дальнейшей обработки (например, сбор ошибок в k8s-окружении с отправкой в ELK).
- Можно дублировать ошибки в систему агрегации (например, Sentry), чтобы видеть статистику их появления.
- Для критичных ошибок должна быть настроена система уведомления дежурного инженера.
Запускается по расписанию в cli-режиме (через cron) и валидирует email-адреса.
Для сокращения времени работы скрипта (а также финансовых расходов) делаем допущение, что подтвержденные пользователями адреса уже являются валидными email-адресами, так как пользователь уже благополучно получил письмо для подтверждения.
Таким образом, проверить нужно только еще не подтвержденные адреса (с помощью функции check_email).
Запускается по расписанию в cli-режиме (через cron) и рассылает уведомления о скором завершении подписки.
Всем пользователям, у которых через 1, 2 или 3 дня истечет подписка, отправляется email по заданному шаблону (с помощью функции send_email).
Во избежание лишних уведомлений необходимо запускать скрипт не чаще одного раза в сутки.
В данном решении специфичные настройки скрипта вынесены в виде переменных в начале файла. Для production-окружения это не лучшее решение. Лучше применить один из способов, описанных в разделе "Скрипт db.php".