Retry failed email jobs
This commit is contained in:
@@ -16,6 +16,8 @@ class SendNotificationToUsers implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 5;
|
||||
|
||||
public $users;
|
||||
|
||||
public $conversation;
|
||||
@@ -68,10 +70,25 @@ class SendNotificationToUsers implements ShouldQueue
|
||||
$global_exception = null;
|
||||
|
||||
foreach ($this->users as $user) {
|
||||
|
||||
// If for one user sending fails the job is marked as failed and retried after some time.
|
||||
// So we have to check if notification email has already been successfully sent to this user.
|
||||
if ($this->attempts() > 1) {
|
||||
// Maybe add indexes to the table.
|
||||
$already_sent = SendLog::where('thread_id', $last_thread->id)
|
||||
->where('mail_type', SendLog::MAIL_TYPE_USER_NOTIFICATION)
|
||||
->where('user_id', $user->id)
|
||||
->whereIn('status', SendLog::$sent_success)
|
||||
->exists();
|
||||
if ($already_sent) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$message_id = \App\Misc\Mail::MESSAGE_ID_PREFIX_NOTIFICATION.'-'.$last_thread->id.'-'.$user->id.'-'.time().'@'.$mailbox->getEmailDomain();
|
||||
$headers['Message-ID'] = $message_id;
|
||||
|
||||
// If this is notification on message from customer set customer as sender name
|
||||
// If this is notification on message from customer, set customer as sender name
|
||||
$from_name = '';
|
||||
if ($last_thread->type == Thread::TYPE_CUSTOMER) {
|
||||
$from_name = $last_thread->customer->getFullName();
|
||||
@@ -125,7 +142,14 @@ class SendNotificationToUsers implements ShouldQueue
|
||||
}
|
||||
|
||||
if ($global_exception) {
|
||||
throw $global_exception;
|
||||
// Retry job with delay.
|
||||
// https://stackoverflow.com/questions/35258175/how-can-i-create-delays-between-failed-queued-job-attempts-in-laravel
|
||||
if ($this->attempts() <= $this->tries) {
|
||||
$this->release(3600);
|
||||
throw $global_exception;
|
||||
} else {
|
||||
$this->fail($global_exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ class SendReplyToCustomer implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 5;
|
||||
|
||||
public $conversation;
|
||||
|
||||
public $threads;
|
||||
@@ -123,7 +125,14 @@ class SendReplyToCustomer implements ShouldQueue
|
||||
// Save to send log
|
||||
$this->saveToSendLog($e->getMessage());
|
||||
|
||||
throw $e;
|
||||
// Retry job with delay.
|
||||
// https://stackoverflow.com/questions/35258175/how-can-i-create-delays-between-failed-queued-job-attempts-in-laravel
|
||||
if ($this->attempts() <= $this->tries) {
|
||||
$this->release(3600);
|
||||
throw $e;
|
||||
} else {
|
||||
$this->fail($e);
|
||||
}
|
||||
}
|
||||
|
||||
// In message_id we are storing Message-ID of the incoming email which created the thread
|
||||
|
||||
@@ -22,6 +22,20 @@ class SendLog extends Model
|
||||
const STATUS_UNSUBSCRIBED = 8;
|
||||
const STATUS_COMPLAINED = 9;
|
||||
|
||||
/**
|
||||
* Status determining successfull sending.
|
||||
*
|
||||
* @var [type]
|
||||
*/
|
||||
public static $sent_success = [
|
||||
self::STATUS_ACCEPTED,
|
||||
self::STATUS_DELIVERY_SUCCESS,
|
||||
self::STATUS_OPENED,
|
||||
self::STATUS_CLICKED,
|
||||
self::STATUS_UNSUBSCRIBED,
|
||||
self::STATUS_COMPLAINED,
|
||||
];
|
||||
|
||||
/**
|
||||
* Mail types.
|
||||
*/
|
||||
|
||||
@@ -177,9 +177,12 @@ return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Parameters used to run queued jobs processing.
|
||||
| Checks for new jobs every 5 seconds.
|
||||
| Do not set more than 1 retry, as it may lead to sending repeated emails if one recipient fails
|
||||
| and another succeeds.
|
||||
| Checks for new jobs every --sleep seconds.
|
||||
| If --tries is set and job fails it is being processed right away without any delay.
|
||||
| --delay parameter does not work to set delays between retry attempts.
|
||||
/
|
||||
| Jobs sending emails are retried manually in handle().
|
||||
| Number of retries is set in each job class.
|
||||
|-------------------------------------------------------------------------
|
||||
*/
|
||||
'queue_work_params' => ['--queue' => 'emails,default', '--sleep' => '5', '--tries' => '1'],
|
||||
|
||||
@@ -38,6 +38,7 @@ return [
|
||||
'driver' => 'database',
|
||||
'table' => 'jobs',
|
||||
'queue' => 'default',
|
||||
// Retry after does not work as delay between retry attempts.
|
||||
'retry_after' => 90,
|
||||
],
|
||||
|
||||
|
||||
@@ -354,20 +354,21 @@
|
||||
@if ( $thread->opened_at )
|
||||
<div class='thread-opened-at'><i class="glyphicon glyphicon-eye-open"></i> {{ __("Customer viewed") }} {{ App\User::dateDiffForHumansWithHours($thread->opened_at) }}</div>
|
||||
@endif
|
||||
|
||||
@if ($thread->has_attachments)
|
||||
<div class="thread-attachments">
|
||||
<i class="glyphicon glyphicon-paperclip"></i>
|
||||
<ul>
|
||||
@foreach ($thread->attachments as $attachment)
|
||||
<li>
|
||||
<a href="{{ $attachment->url() }}" class="break-words" target="_blank">{{ $attachment->file_name }}</a>
|
||||
<span class="text-help">({{ $attachment->getSizeName() }})</span>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@if ($thread->has_attachments)
|
||||
<div class="thread-attachments">
|
||||
<i class="glyphicon glyphicon-paperclip"></i>
|
||||
<ul>
|
||||
@foreach ($thread->attachments as $attachment)
|
||||
<li>
|
||||
<a href="{{ $attachment->url() }}" class="break-words" target="_blank">{{ $attachment->file_name }}</a>
|
||||
<span class="text-help">({{ $attachment->getSizeName() }})</span>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="dropdown thread-options">
|
||||
<span class="dropdown-toggle glyphicon glyphicon-option-vertical" data-toggle="dropdown"></span>
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ __('Failed At') }}</td>
|
||||
<td>{{ App\User::dateFormat($job->failed_at) }}</td>
|
||||
<td>{{ App\User::dateFormat($job->failed_at, 'M j, Y H:i:s') }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user