From 11cfb80c9d82311364ceb9c766f444259e136395 Mon Sep 17 00:00:00 2001 From: Kenneth Ormandy Date: Fri, 8 Mar 2024 12:44:26 -0800 Subject: [PATCH 1/4] Adds faster calculation of expected recipients for regular sendouts --- src/elements/SendoutElement.php | 6 ++++- src/services/SendoutsService.php | 42 ++++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/elements/SendoutElement.php b/src/elements/SendoutElement.php index d3a69788..4bcd14c2 100755 --- a/src/elements/SendoutElement.php +++ b/src/elements/SendoutElement.php @@ -1040,7 +1040,11 @@ public function getPendingRecipients(): array */ public function getPendingRecipientCount(): int { - return count($this->getPendingRecipients()); + if ($this->_pendingRecipients !== null) { + return count($this->_pendingRecipients); + } + + return Campaign::$plugin->sendouts->getPendingRecipientCount($this); } /** diff --git a/src/services/SendoutsService.php b/src/services/SendoutsService.php index ee27ed45..1481c5c7 100755 --- a/src/services/SendoutsService.php +++ b/src/services/SendoutsService.php @@ -130,7 +130,16 @@ public function getPendingRecipients(SendoutElement $sendout): array */ public function getPendingRecipientCount(SendoutElement $sendout): int { - return count($this->getPendingRecipients($sendout)) - $sendout->failures; + $count = 0; + + // TODO Do this for all sendout types, so only IDs are queried at this stage + if ($sendout->sendoutType == 'regular') { + $count = count($this->_getPendingRecipientsStandardIds($sendout)); + } else { + $count = count($this->getPendingRecipients($sendout)); + } + + return $count - $sendout->failures; } /** @@ -588,17 +597,27 @@ private function _getSentRecipientsQuery(SendoutElement $sendout, bool $todayOnl } /** - * Returns the standard sendout's pending contact IDs. + * Returns the standard sendout’s shared base query condition config. */ - private function _getPendingRecipientsStandard(SendoutElement $sendout): array + private function _getPendingRecipientsStandardBaseCondition(SendoutElement $sendout): array { - App::maxPowerCaptain(); - $baseCondition = [ 'mailingListId' => $sendout->mailingListIds, 'subscriptionStatus' => 'subscribed', ]; + return $baseCondition; + } + + /** + * Returns the standard sendout’s pending contact IDs. + */ + private function _getPendingRecipientsStandardIds(SendoutElement $sendout): array + { + App::maxPowerCaptain(); + + $baseCondition = $this->_getPendingRecipientsStandardBaseCondition($sendout); + // Get contacts subscribed to sendout's mailing lists $query = ContactMailingListRecord::find() ->select(['contactId', 'min([[mailingListId]]) as mailingListId', 'min([[subscribed]]) as subscribed']) @@ -633,6 +652,19 @@ private function _getPendingRecipientsStandard(SendoutElement $sendout): array } } + return $contactIds; + } + + /** + * Returns the standard sendout’s pending contacts. + */ + private function _getPendingRecipientsStandard(SendoutElement $sendout): array + { + App::maxPowerCaptain(); + + $baseCondition = $this->_getPendingRecipientsStandardBaseCondition($sendout); + $contactIds = $this->_getPendingRecipientsStandardIds($sendout); + // Get recipients as array return ContactMailingListRecord::find() ->select(['contactId', 'min([[mailingListId]]) as mailingListId', 'min([[subscribed]]) as subscribed']) From db8791288a2c7069b46c0055f0ab539358b3e3b7 Mon Sep 17 00:00:00 2001 From: Kenneth Ormandy Date: Fri, 8 Mar 2024 12:46:58 -0800 Subject: [PATCH 2/4] Adds batch query when querying regular sendout recipients --- src/services/SendoutsService.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/services/SendoutsService.php b/src/services/SendoutsService.php index 1481c5c7..51667784 100755 --- a/src/services/SendoutsService.php +++ b/src/services/SendoutsService.php @@ -665,15 +665,23 @@ private function _getPendingRecipientsStandard(SendoutElement $sendout): array $baseCondition = $this->_getPendingRecipientsStandardBaseCondition($sendout); $contactIds = $this->_getPendingRecipientsStandardIds($sendout); + $contacts = []; + // Get recipients as array - return ContactMailingListRecord::find() + $contactsQuery = ContactMailingListRecord::find() ->select(['contactId', 'min([[mailingListId]]) as mailingListId', 'min([[subscribed]]) as subscribed']) ->groupBy('contactId') ->where($baseCondition) ->andWhere(['contactId' => $contactIds]) ->orderBy(['contactId' => SORT_ASC]) - ->asArray() - ->all(); + ->asArray(); + + // Fetch 10,000 contacts at a time + foreach($contactsQuery->each(10000) as $contact) { + $contacts[] = $contact; + } + + return $contacts; } /** From d267fbeead51113e4a7a160beeb7650d1598f661 Mon Sep 17 00:00:00 2001 From: Ben Croker <57572400+bencroker@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:54:44 -0600 Subject: [PATCH 3/4] Revert changes --- src/elements/SendoutElement.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/elements/SendoutElement.php b/src/elements/SendoutElement.php index 4bcd14c2..d3a69788 100755 --- a/src/elements/SendoutElement.php +++ b/src/elements/SendoutElement.php @@ -1040,11 +1040,7 @@ public function getPendingRecipients(): array */ public function getPendingRecipientCount(): int { - if ($this->_pendingRecipients !== null) { - return count($this->_pendingRecipients); - } - - return Campaign::$plugin->sendouts->getPendingRecipientCount($this); + return count($this->getPendingRecipients()); } /** From b58bda0248fe23a7f65b14cce19f4df079b0b19b Mon Sep 17 00:00:00 2001 From: Ben Croker <57572400+bencroker@users.noreply.github.com> Date: Fri, 8 Mar 2024 19:31:31 -0600 Subject: [PATCH 4/4] Remove batching, code cleanup --- src/services/SendoutsService.php | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/services/SendoutsService.php b/src/services/SendoutsService.php index 51667784..ce08ad13 100755 --- a/src/services/SendoutsService.php +++ b/src/services/SendoutsService.php @@ -130,10 +130,7 @@ public function getPendingRecipients(SendoutElement $sendout): array */ public function getPendingRecipientCount(SendoutElement $sendout): int { - $count = 0; - - // TODO Do this for all sendout types, so only IDs are queried at this stage - if ($sendout->sendoutType == 'regular') { + if ($sendout->sendoutType === 'regular') { $count = count($this->_getPendingRecipientsStandardIds($sendout)); } else { $count = count($this->getPendingRecipients($sendout)); @@ -597,16 +594,14 @@ private function _getSentRecipientsQuery(SendoutElement $sendout, bool $todayOnl } /** - * Returns the standard sendout’s shared base query condition config. + * Returns the standard sendout’s base query condition. */ private function _getPendingRecipientsStandardBaseCondition(SendoutElement $sendout): array { - $baseCondition = [ + return [ 'mailingListId' => $sendout->mailingListIds, 'subscriptionStatus' => 'subscribed', ]; - - return $baseCondition; } /** @@ -665,23 +660,15 @@ private function _getPendingRecipientsStandard(SendoutElement $sendout): array $baseCondition = $this->_getPendingRecipientsStandardBaseCondition($sendout); $contactIds = $this->_getPendingRecipientsStandardIds($sendout); - $contacts = []; - // Get recipients as array - $contactsQuery = ContactMailingListRecord::find() + return ContactMailingListRecord::find() ->select(['contactId', 'min([[mailingListId]]) as mailingListId', 'min([[subscribed]]) as subscribed']) ->groupBy('contactId') ->where($baseCondition) ->andWhere(['contactId' => $contactIds]) ->orderBy(['contactId' => SORT_ASC]) - ->asArray(); - - // Fetch 10,000 contacts at a time - foreach($contactsQuery->each(10000) as $contact) { - $contacts[] = $contact; - } - - return $contacts; + ->asArray() + ->all(); } /**