phpcronsilverstripe

Silverstripe 4.11 queuedjobs send emails in Chunks timeperiode


With Silverstripe 4.11 and silverstripe-queuedjobs i am trying to send emails in chunks of 4 emails every given time-period.

(every chunk sends a email to 4 recipients of (100 recipients) every given period)

chunk 1 sending email to recipient A, B , C , D

wait a given time

chunk 2 sending email to recipient E, F, G, H

and so on....

I have tried to use sleep() to pause the execution of chunk sending (in this case 2 minutes) but that makes the whole website unresponsive. (and the animated Silverstripe-logo is visible in the queue).

Is there a way (a built in function in silverstripe-queuedjobs module) to send the emails in chunks of 4 (private static $chunk_size) and have a delay between?

Or is this the point to work with a cron-job and silverstripe-queuedjobs in combination?

Can you provide an example to archive this purpose?

Thanks for helping.

Thats what i have so far:

class SendEmailsJob extends AbstractQueuedJob implements QueuedJob
{
    private static $chunk_size = 4;

    public function getTitle()
    {
        return 'Send Emails in Chunks';
    }

    public function process()
    {
        $recipients = Recipient::get(); // Assuming Recipients is your DataObject

        // Calculate the total number of chunks
        $totalChunks = ceil($recipients->count() / self::$chunk_size);

        for ($chunk = 0; $chunk < $totalChunks; $chunk++) {
            $start = $chunk * self::$chunk_size;
            $end = ($chunk + 1) * self::$chunk_size;

            $chunkRecipients = $recipients->limit(self::$chunk_size, $start);

            foreach ($chunkRecipients as $recipient) {
                // Send email to $recipient
                $email = Email::create()
                    ->setTo($recipient->Email)
                    ->setSubject('Your Email Subject')
                    ->setBody('Your Email Body')
                    ->send();
            }

            // Sleep for a while to respect the host's email sending limits
            sleep(120); // 2 minutes // 3600 Sleep for 1 hour (adjust as needed)

            // Update the job progress
            $this->currentStep = $chunk + 1;
            $this->totalSteps = $totalChunks;
            $this->addMessage("Processed chunk {$this->currentStep}/{$this->totalSteps}");
        }

        $this->isComplete = true;
    }
}

Solution

  • Is there a way (a built in function in silverstripe-queuedjobs module) to send the emails in chunks of 4 (private static $chunk_size) and have a delay between?

    The way to do this would be to create a new job for each chunk, where each job has its own starting time.