How to Make a Scheduler Task for Every New Record After 20 Minutes in Laravel?

冷暖自知 提交于 2019-12-11 07:57:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!