问题
I have a Parking System that I use Angular 6 + Laravel for the backend, and I have a specific problem that I don't know the right approach.
The Park has two totem's that send to my server an entry. I check if the client is invalid only when he goes out on the totem from the exit and when he goes to the payment area.
This is my code when he put the ticket that has EAN_13 barcode read. This is my code that is ready by the Exit Totem:
public function getEntrysDataByEan(Request $request)
{
if (isset($request)) {
$entryean = $request->input('entryean13');
$entry = $this->mdMovEntry->getEntrysDataByEan($entryean);
if (empty($entry)) {
$response["success"] = 0;
$response["message"] = "Não existe nenhuma entrada correspondente";
} else {
$nowHour = Carbon::now();
$enterHour = Carbon::parse($entry[0]->updated_at);
$difmin = $enterHour->diffInMinutes($nowHour);
$dif = $enterHour->diffInHours($nowHour);
if ($difmin <= 20) {
$this->mdMovEntry->validatedEntryByEan($entryean, Carbon::parse($entry[0]->updated_at), $nowHour);
$entry[0]->validated = 'S';
} else {
$this->mdMovEntry->devaluedEntryByEan($entryean, Carbon::parse($entry[0]->updated_at));
$entry[0]->validated = 'N';
}
$response["success"] = 1;
$response["message"] = "Entrada retornada com sucesso";
$response["entry"] = $entry;
}
} else {
$response["success"] = 0;
$response["message"] = "Nenhum dado enviado";
}
return $response;
}
The problem is that I think is so much processing to just read if the client can go out or not, so I search the Task Scheduling approach and Job approach from Laravel and don't find anything for my problem.
What I want is when the Totem from entry area makes an insert on my database I create some Job or Task that after 20 min for every new record he put to invalidated.
And when the client goes out, the system just does a getEntry on the database and check if he is validated or not.
How I can achieve this? I ask this because every example for the Task is a global execution but I only want a task for every new record it is possible?
回答1:
Consider using model events in conjunction with delayed dispatching for queued jobs.
The following will listen for the created
event when new entries are inserted into the database and dispatch a job delayed by 20 minutes to later invalidate the entry.
InvalidateEntry Job
class InvalidateEntry implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $entry;
/**
* Create a new job instance.
*
* @param Entry $entry
* @return void
*/
public function __construct(Entry $entry)
{
$this->entry = $entry;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// you'll probably need to add some conditional logic
// before updating the entry to determine if the
// action is still required.
$isEntryInvalid = ...;
if ($isEntryInvalid) {
$this->entry->update([
'validated' => 'N'
]);
} else {
// delete the job from the queue
$this->delete();
}
}
}
Entry Model
class Entry extends Model
{
public static function boot()
{
parent::boot();
static::created(function (Entry $entry) {
InvalidateEntry::dispatch($entry)->delay(now()->addMinutes(20));
});
}
}
来源:https://stackoverflow.com/questions/54175020/how-to-make-a-scheduler-task-for-every-new-record-after-20-minutes-in-laravel