Deactivate inactive subscribers by ID range for performance reasons [MAILPOET-2392]

This commit is contained in:
wxa
2019-10-09 12:09:12 +03:00
committed by Jack Kitterhing
parent d8ccb8a88c
commit 622ae8d4df
3 changed files with 30 additions and 9 deletions

View File

@ -4,6 +4,7 @@ namespace MailPoet\Cron\Workers;
use MailPoet\Cron\CronHelper;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\Subscriber;
use MailPoet\Settings\SettingsController;
use MailPoet\Subscribers\InactiveSubscribersController;
@ -43,7 +44,17 @@ class InactiveSubscribers extends SimpleWorker {
return true;
}
// Handle activation/deactivation within interval
while ($this->inactive_subscribers_controller->markInactiveSubscribers($days_to_inactive, self::BATCH_SIZE) === self::BATCH_SIZE) {
$meta = $task->getMeta();
$last_subscriber_id = isset($meta['last_subscriber_id']) ? $meta['last_subscriber_id'] : 0;
$max_subscriber_id = isset($meta['max_subscriber_id']) ? $meta['max_subscriber_id'] : (int)Subscriber::max('id');
while ($last_subscriber_id <= $max_subscriber_id) {
$count = $this->inactive_subscribers_controller->markInactiveSubscribers($days_to_inactive, self::BATCH_SIZE, $last_subscriber_id);
if ($count === false) {
break;
}
$last_subscriber_id += self::BATCH_SIZE;
$task->meta = ['last_subscriber_id' => $last_subscriber_id];
$task->save();
CronHelper::enforceExecutionLimit($this->timer);
};
while ($this->inactive_subscribers_controller->markActiveSubscribers($days_to_inactive, self::BATCH_SIZE) === self::BATCH_SIZE) {

View File

@ -106,6 +106,14 @@ use MailPoet\WP\Functions as WPFunctions;
* @method static $this|bool create($data=null)
* @method int count()
* @method static int count()
* @method int sum($column_name)
* @method int min($column_name)
* @method int max($column_name)
* @method int avg($column_name)
* @method static int sum($column_name)
* @method static int min($column_name)
* @method static int max($column_name)
* @method static int avg($column_name)
* @method static static limit(int $limit)
* @method static static distinct()
* @method $this set(string|array $key, string|null $value = null)

View File

@ -16,11 +16,11 @@ class InactiveSubscribersController {
/**
* @param int $days_to_inactive
* @param int $batch_size
* @return int
* @return int|boolean
*/
function markInactiveSubscribers($days_to_inactive, $batch_size) {
function markInactiveSubscribers($days_to_inactive, $batch_size, $start_id = null) {
$threshold_date = $this->getThresholdDate($days_to_inactive);
return $this->deactivateSubscribers($threshold_date, $batch_size);
return $this->deactivateSubscribers($threshold_date, $batch_size, $start_id);
}
/**
@ -56,9 +56,9 @@ class InactiveSubscribersController {
/**
* @param Carbon $threshold_date
* @param int $batch_size
* @return int
* @return int|boolean
*/
private function deactivateSubscribers(Carbon $threshold_date, $batch_size) {
private function deactivateSubscribers(Carbon $threshold_date, $batch_size, $start_id = null) {
$subscribers_table = Subscriber::$_table;
$scheduled_tasks_table = ScheduledTask::$_table;
$scheduled_task_subcribres_table = ScheduledTaskSubscriber::$_table;
@ -92,18 +92,20 @@ class InactiveSubscribersController {
// because they are imported with original subscription date but they were not present in a list for whole period
$mp2_migration_date = $this->getMP2MigrationDate();
if ($mp2_migration_date && $mp2_migration_date > $threshold_date) {
return 0;
return false;
}
// Select subscribers who received a recent tracked email but didn't open it
$start_id = (int)$start_id;
$end_id = $start_id + $batch_size;
$ids_to_deactivate = \ORM::forTable($subscribers_table)->rawQuery("
SELECT s.id FROM $subscribers_table as s
JOIN $scheduled_task_subcribres_table as sts ON s.id = sts.subscriber_id
JOIN inactives_task_ids task_ids ON task_ids.id = sts.task_id
LEFT OUTER JOIN $statistics_opens_table as so ON s.id = so.subscriber_id AND so.created_at > ?
WHERE s.last_subscribed_at < ? AND s.status = ? AND so.id IS NULL
WHERE s.last_subscribed_at < ? AND s.status = ? AND so.id IS NULL AND s.id >= ? AND s.id < ?
GROUP BY s.id LIMIT ?",
[$threshold_date_iso, $threshold_date_iso, Subscriber::STATUS_SUBSCRIBED, $batch_size]
[$threshold_date_iso, $threshold_date_iso, Subscriber::STATUS_SUBSCRIBED, $start_id, $end_id, $batch_size]
)->findArray();
$ids_to_deactivate = array_map(