From 832e49bb99c42a6141b08855c564e169d2a51ce5 Mon Sep 17 00:00:00 2001 From: Jens Pfeifer Date: Thu, 14 Dec 2023 11:49:54 +0000 Subject: [PATCH] Kernel::System::MailQueue::Send now ensures number of attempts getting increased before sending an email in case the process dies. --- CHANGES.md | 3 ++ Kernel/System/MailQueue.pm | 62 +++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c54d039216f..e4c14ff6f69 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +# 6.5.6 2024-??-?? + - 2023-10-24 Kernel::System::MailQueue::Send now increases number of attempts before sending an email. This prevents the attempts not being increased if the process dies while trying to send an email. + # 6.5.5 2023-12-13 - 2023-12-11 Increased size of user_id column in table customer_user_customer. - 2023-12-07 Customer detail search cache for dynamic field values will now be cleared if a customer will be added or updated. diff --git a/Kernel/System/MailQueue.pm b/Kernel/System/MailQueue.pm index e34a4b2ad5a..73dbdfbebad 100644 --- a/Kernel/System/MailQueue.pm +++ b/Kernel/System/MailQueue.pm @@ -640,6 +640,58 @@ sub Send { $Param{CommunicationLogObject} = $Self->_GetCommunicationLog( %Param, ); $Param{CommunicationID} = $Param{CommunicationLogObject}->CommunicationIDGet(); + # Increase number of attempts and delete item if limit has been reached. + $Param{Attempts} //= 0; + $Param{Attempts}++; + my %UpdateData = ( + Attempts => $Param{Attempts}, + ); + my $ItemUpdateOK = $Self->Update( + Filters => { + ID => $Param{ID}, + }, + Data => \%UpdateData, + ); + + if ( !$ItemUpdateOK ) { + my $LogMessage = sprintf( + 'Error while updating mail queue element "%s" with "%s"!', + $Param{ID}, + join( ', ', map { $_ . '=' . $UpdateData{$_} } sort keys %UpdateData ), + ); + + $LogObject->Log( + Priority => 'error', + Message => $LogMessage, + ); + + $Param{CommunicationLogObject}->ObjectLog( + ObjectLogType => 'Message', + Priority => 'Error', + Key => 'Kernel::System::MailQueue', + Value => $LogMessage, + ); + + return; + } + + my $Config = $Kernel::OM->Get('Kernel::Config')->Get('MailQueue'); + my $MaxAttempts = $Config->{ItemMaxAttempts}; + if ( $Param{Attempts} > $MaxAttempts ) { + + # This will lead to _SendError executing the code for reaching limit of attempts + # and hence deleting the item from the queue. + $Self->_SendError( + Item => \%Param, + SendResult => {}, + ); + + return { + Status => 'Failed', + Message => 'Sending has failed.', + }; + } + # If DueTime is bigger than current time, skip, it is not time to run yet. my $CurrentSysDTObject = $Kernel::OM->Create('Kernel::System::DateTime'); my $DueTime = $Param{DueTime}; @@ -694,7 +746,7 @@ sub Send { return { Status => 'Failed', - Message => 'Sending has Failed.' + Message => 'Sending has failed.' }; } @@ -829,7 +881,7 @@ sub _SendError { my $SendResult = $Param{SendResult}; my $Item = $Param{Item}; - my $ItemAttempts = $Item->{Attempts} + 1; + my $ItemAttempts = $Item->{Attempts}; my $ItemMaxAttempts = $Config->{ItemMaxAttempts}; $Item->{CommunicationLogObject}->ObjectLog( @@ -910,10 +962,10 @@ sub _SendError { my $NextAttempt = $CurrentSysDTObject->Clone(); $NextAttempt->Add( Minutes => $ItemAttempts * $MinutesToIncrement ); - # Update mail-queue with attempt and smtp code and message. + # Update mail-queue with smtp code and message. + # Note: Attempts already have been incremented in Send(). my %UpdateData = ( - Attempts => $ItemAttempts, - DueTime => $NextAttempt->ToString(), + DueTime => $NextAttempt->ToString(), ); if ( $SendResult->{SMTPError} ) {