File: /home/xedaptot/ai.naniguide.com/app/Jobs/BulkCheck.php
<?php
namespace App\Jobs;
use Illuminate\Bus\Batchable;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Library\Traits\Trackable;
use App\Library\Contracts\CreditTrackerInterface;
use App\Library\Contracts\BulkVerificationTargetInterface;
use App\Model\EmailVerificationServer;
use Exception;
class BulkCheck implements ShouldQueue
{
use Trackable;
use Batchable;
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
public $timeout = 900;
public $maxExceptions = 1; // This is required if retryUntil is used, otherwise, the default value is 255
public $failOnTimeout = true;
protected $server;
protected $list;
protected $token;
protected $customer;
/**
* Same serialization requirement as BulkVerify: the tracker must hold no mutable state
* in PHP memory. Its state (remaining credits) must live in an external store (disk or cache)
* so that after Laravel deserializes this job from the queue, every read/write goes to the
* same external source and reflects the current value — not a snapshot from dispatch time.
*
* Null means no credit limit applies (no subscription / non-SaaS).
*/
protected ?CreditTrackerInterface $creditTracker;
public function __construct(BulkVerificationTargetInterface $list, EmailVerificationServer $server, ?CreditTrackerInterface $creditTracker, $token)
{
$this->list = $list;
$this->server = $server;
$this->creditTracker = $creditTracker;
$this->token = $token;
$this->customer = $this->list->customer;
}
/**
* Determine the time at which the job should timeout.
*
* @return \DateTime
*/
public function retryUntil()
{
// @important: remember that messages might be released over and over
// if there is any limit setting in place
// As a result, it is just save to have it retry virtually forever
return now()->addDays(7);
}
public function handle()
{
$this->customer->setUserDbConnection();
if ($this->batch()->cancelled()) {
$this->list->logger()->info('[BulkCheck] Cancelled, token: '.$this->token);
return;
}
$this->list->logger()->info('[BulkCheck] Checking with token: '.$this->token);
$results = [];
$driver = $this->server->driver();
try {
$check = $driver->bulkCheck($this->token, function ($email, $verificationStatus, $raw) use (&$results) {
$results[] = [
'email' => $email,
'status' => $verificationStatus,
'raw' => $raw,
];
}, function (string $response, $batchId = null, $batchSize = null, $processed = null) {
if ($batchId && $batchSize) {
$this->monitor->updateJsonData([
'batch_info' => trans('messages.list.verification.progress.batch_info', [
'j' => $batchId,
'p' => $processed,
't' => $batchSize,
])
]);
}
$this->list->logger()->info('[BulkCheck] Wait: '.$response);
});
} catch (\ZeroBounce\SDK\ZBException $ex) {
// In case of stupid error by ZB
$this->list->logger()->info('[BulkCheck] \ZeroBounce\\SDK\\ZBException from ZB, release(10) and wait. Error: '.$ex->getMessage());
$this->release(10);
return;
} catch (\Throwable $ex) {
$this->list->logger()->warning('[BulkCheck] Failed (catched by Throwable), throw exception. Error: '.$ex->getMessage());
throw new Exception('Verification CHECK failed. '.$ex->getMessage());
}
if ($check) {
$this->list->updateVerificationResults($results, $this->server->name);
$count = $this->monitor->getJsonData()['count'] ?? 0;
$count += sizeof($results);
$percentageDone = round($this->list->getVerifiedSubscribersPercentage() * 100, 2);
$msg = trans('messages.list.verification.progress.running', [
'c' => $count,
'v' => $this->list->getVerifiedSubscribersCount(),
't' => $this->list->getSubscribersCount(),
]);
$this->monitor->updateJsonData([
'message' => $msg,
'percentage' => $percentageDone,
'count' => $count,
]);
$this->list->logger()->info('[BulkCheck] List % verified: '.$percentageDone);
// Check done, launch a new round
$job = new BulkVerify($this->list, $this->server, $this->creditTracker);
$job->setMonitor($this->monitor);
$this->batch()->add($job);
return;
} else {
$this->list->logger()->info('[BulkCheck] Check again in 10 seconds');
// wait until result is available, check again
$this->release(10);
return;
}
}
}