Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
597 views
in Technique[技术] by (71.8m points)

php - Cancel Jobs In Laravel

If I call the following:

return AdventureJob::dispatch($event->character->refresh(), $event->adventure, $event->levelsAtATime)->delay($timeTillFinished);

This will then create a job thats delayed x minutes. my jobs are all processed through redis, is there a way to then get this specific job or delete this specific job from the queue?

People talk about php artisan commands to then delete all jobs, thats not what I want I want to get some kind of information (Job ID? or queue ID? Redis ID?) about this job to then store in the database so that if the player then cancels the adventure, I can use that to find this job on the queue and delete it, assuming it's not running.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is no direct or easy way to do it. The delayed jobs are kept in sorted sets as to-be-processed time as score and job payload as the value.

There are several ways to remove an element from the sorted sets(most of them require some efforts depending on the size of the delayed queue) such as

  • You get the "exact" payload of the dispatched job and then use ZREM to remove it. It is hard because the object(serialized version of the job with all the parameters) can be huge and you can't create the "exact" job because it has a unique identifier. You can get the list of it with ZRANGEBYSCORE and with WITHSCORES. It will give you the list of jobs with their scores. You can use score to identify to be delayed job. Get the value(serialized payload) then use ZREM.
  • If there is only one job to be processed at a specific time you, may use ZREMRANGEBYSCORE with using the processed time. If there are n jobs to be processed exactly that time then other jobs can be deleted too since ZREMRANGEBYSCORE takes time interval.
  • You may try to use ZSCAN to scan the whole delayed list(with pagination) and find the score and identifier of the job, and then use ZREMRANGEBYLEX with the identifier to remove it.
  • Another way could be putting a cancellation condition at the beginning of handle method. This one requires application layer development. Whenever you push a job to the queue you send an identifier to the job, put same identifier(that you can understand) in Redis too(with EXPIRE greater than the delayed time). When you want to cancel it, then delete it from the Redis. Inside the handle method check whether the given identifier exists in Redis, if not early return from the code block.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...