Skip to content

Instantly share code, notes, and snippets.

@tmyers273
Created December 10, 2016 18:38
Show Gist options
  • Save tmyers273/ebea6cc4c72b77dfddee30c279f315ce to your computer and use it in GitHub Desktop.
Save tmyers273/ebea6cc4c72b77dfddee30c279f315ce to your computer and use it in GitHub Desktop.
Laravel Queued Job Debounce

This provides a relatively easy way to debounce queued jobs.

A hash is created for a given job based on it's parameters. This hash value is then used as a cache key to store the most recently dispatched job id.

When running, if the value in the cache is equal to the current job id, then we continue running. If it's not, then we know it's an old job and exit.

<?php
namespace App\Jobs;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Cache;
abstract class DebouncedJob extends Job {
use InteractsWithQueue;
protected $params;
public function __construct($params)
{
$this->params = $params;
}
public function shouldBeRun()
{
$jobId = $this->job->getJobId();
$expectedJobId = Cache::get($this->getCacheKey());
if ($jobId != $expectedJobId) {
return false;
}
return true;
}
public function getCacheKey()
{
$hash = $this->getHash();
return 'debounced_job:' . $hash;
}
public function getHash()
{
return $this->hash($this->getHashString());
}
protected function getHashString()
{
return json_encode([
'class' => get_class($this),
'params' => json_encode($this->params)
]);
}
protected function hash($string)
{
return md5($string);
}
}
<?php
namespace App\Jobs;
use Illuminate\Support\Facades\Cache;
trait DispatchesDebouncedJobs {
use \Illuminate\Foundation\Bus\DispatchesJobs;
/**
* Dispatches a debounced job
*
* @param DebouncedJob|Job $job
* @param int $delay in seconds
* @param null $params optional parameters to hash against
* @return mixed
*/
protected function dispatchDebounced(DebouncedJob $job, $delay = 10, $params = null)
{
$jobId = $this->dispatch($job->delay($delay));
Cache::put($job->getCacheKey(), $jobId, $this->getCacheTime($delay));
echo("<pre>cache key = ");
print_r($job->getCacheKey());
echo("\n");
echo("<pre>job id = ");
print_r($jobId);
return $jobId;
}
protected function getCacheTime($delay)
{
return ceil($delay / 60) + 1;
}
}
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
class UpdateDailyOverviewForUser extends DebouncedJob implements SelfHandling, ShouldQueue
{
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($userId)
{
parent::__construct(func_get_args());
// Normal constructor
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
if (! $this->shouldBeRun()) {
echo("Debounced.\n");
$this->delete();
return;
}
// Normal Handle
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment