Merhaba,
Belirli süre aralıkları ile kontrol edip işlediğim bir job akışım mevcut. Laravel'in sağladığı atomic lock yapısını da kullanarak arka arkaya veri girişi yapılmasını da engelliyorum. Ama verdiğim süreler bazen yetmiyor ve job listem sürekli şişiyor. Burada aynı verileri tekrar tekrar kontrol etme durumu da söz konusu.Şu an yapmaya çalıştığım işlem şu ki eğer içeriye önceden eklediğim bir değer varsa ve değerleri son gelen değerler ile aynıysa son eklenen jobu temizlemek. Eğer son gelen işçi sınıfının değerleri bir önceki veri setine göre daha güncel ise işlenmeyen jobu temizleyip yeni değerlere zaman açılması.
Konuyu hem database hem de redis kuyruk yapılandırmasına göre değerlendirmek istiyorum. Şu an veritabanı yapısına göre çalıştırıyorum ama rediste jobID'ye göre jobu kill etme durumunu bulamadım
$this->optionsExtra[OptionsExtra::cacheLockTime] = 1800;
$data = new \stdClass();
$data->productCode = 'Test';
$data->price = 125;
$md5 = md5(json_encode($data));
$data->lockKey = 'testKey';
$lock = Cache::lock($data->LockKey, $this->optionsExtra[OptionsExtra::cacheLockTime]);
if ($lock->get()) {
$data->Owner = $lock->owner();
$job = (new TestJob($data))->onConnection(config('app.queue_custom_connection') ?
config('app.queue_connection_database') : config('app.queue_connection'))
->onQueue('queue1');
$jobID = app(Dispatcher::class)->dispatch($job);
$this->dublicateJobControl($data->lockKey, $jobID, $md5);
}
Yukarıdaki işlemde veri seti geldi. Bunun md5'ini alıp bununla ilgili bir görev kaydı oluşturdum. Md5 değerlerini redis'te cacheledim.
protected function dublicateJobControl(string $lockKey, string|int $jobID, string $newMD5): void
{
$driver = 'redis';
if (Cache::driver($driver)->has('dublicate-' . $lockKey)) {
$cacheData = Cache::driver($driver)->get('dublicate-' . $lockKey);
$killJobID = $jobID;
if ($cacheData->md5 != $newMD5) {
$killJobID = $cacheData->jobID;
Cache::driver($driver)->set('dublicate-' . $jobID, $lockKey);
Cache::driver($driver)->set('dublicate-' . $lockKey, (object)['md5' => $newMD5, 'jobID' => $jobID]);
}
if (uuid_is_valid($killJobID)) {
} else {
DB::table('jobs')->where('attempts', '!=', 1)->delete($killJobID);
}
Cache::driver($driver)->delete('dublicate-' . $killJobID);
} else {
Cache::driver($driver)->set('dublicate-' . $jobID, $lockKey);
Cache::driver($driver)->set('dublicate-' . $lockKey, (object)['md5' => $newMD5, 'jobID' => $jobID]);
}
}
AppServiceProvider kısmında Queue::before eventını dinleyip cache temizlemesi yapıyorum.
Queue::before(function (JobProcessing $event) {
$jobID = $event->job->getJobId();
if (Cache::driver('redis')->has('dublicate-' . $jobID)) {
Cache::driver('redis')->delete(Cache::driver('redis')->get('dublicate-' . $jobID));
Cache::driver('redis')->delete('dublicate-' . $jobID);
}
});
Redis'in ürettiği uuid job verisini bulup nasıl temizleyebilirim ? Horizon da kullanıyorum. O kısımda jobları bulup içeriğini görüntüleyebiliyorlar. Ama ben tam yolunu bulamadım.
Ayrıca yazdığım bu kodun artı ve eksileri konusunda da fikirlerinizi bekliyorum.