4

I'm useing Laravel 5.1 and it built in Queue service (with Redis driver).

the queue listener look like this:

php artisan queue:listen --tries=5 --delay=60 redis

In the job class itself I check the response and in case it is a positive response I use $this->delete() to remove the job from the queue but with no success, the job still fires 5 times no matter if failed or not.

this is the Job file I uses:

<?php

namespace LM2\Jobs;

use LM2\Http\Controllers\API;
use LM2\Http\Controllers\PredictionsController;
use LM2\Jobs\Job;
use Illuminate\Support\Facades\Log;
use LM2\Http\Controllers\AnalyticsController;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use LM2\Models\Client;
use LM2\Models\GoogleIntegration;
use LM2\Models\Lead;

class CompleteLeadAnalyticsDetails extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    const NUMBER_OF_TRIES = 5;

    private $lead;
    private $client;

    public function __construct(Lead $lead, Client $client)
    {
        $this->lead   = $lead;
        $this->client = $client;
    }

    public function handle(AnalyticsController $analyticsController, API $api,PredictionsController $prediction)
    {
        Log::info("Inside CompleteLeadAnalyticsDetails::handle()");
        $integration = GoogleIntegration::where('client_id', $this->client->id)->first();
        if(count($integration) > 0){
            if($this->attempts() > 1){
                Log::info("CompleteLeadAnalyticsDetails::handle() attempt ".$this->attempts());
                $this->release(120);
                Log::info("CompleteLeadAnalyticsDetails::handle() released");
            }
            try{
                if(count($this->lead->ga_details) > 1){
                    return;
                }
                $res = $analyticsController->getLeadDetails($integration->view_id,$this->lead->ga_details['uacid'],$this->lead->_id,$this->client);
                Log::info("Analytics response: ".$res);
                Log::info('has $res');
                if($res){
                    if(isset($this->lead->email_sent) && (bool)$this->lead->email_sent){
                        return;
                    }else {
                        $prediction->predict($this->lead, $this->client);
                        $api->sendLeadEmail($res, $this->client);
                        $api->forwardToWebService($this->client, $this->lead);
                        Log::info('email sent');
                        $this->delete();
                        return true;
                    }
                }
            }catch (\Exception $e){
                Log::info('no $res, number of attempts:'.$this->attempts()." for lead id:".$this->lead->_id.' number of Attempts: '.$this->attempts());
                if($this->attempts() == self::NUMBER_OF_TRIES){
                    $api->forwardToWebService($this->client,$this->lead);
                    $api->sendLeadEmail($this->lead, $this->client);
                    Log::info('email sent, no $res');
                    $this->delete();
                }
                throw new \Exception('No response for lead id '.$this->lead->_id.' is breaking the job??');
                return false;
            }
        }else{
            if(isset($this->lead->email_sent) && (bool)$this->lead->email_sent){
                return;
            }
            $api->forwardToWebService($this->client,$this->lead);
            $api->sendLeadEmail($this->lead, $this->client);
            Log::info("Client ".$this->client->name.', id:'.$this->client->id.' was not integrate with google CompleteLeadAnalyticsDetails on line:62');
            $this->delete();
        }
        return true;
    }
}

Anyone know why it's happening and what is the solution for it?

Appreciate any help! :)

benjah
  • 613
  • 7
  • 29

2 Answers2

0

use Illuminate\Queue\InteractsWithQueue;

then inside the class add

use InteractsWithQueue;

This will allow you to make those calls

  • Please post the entire job file – johnpaulmedina Apr 18 '16 at 12:59
  • I made a change to the code so at the moment it won't make the tasks inside the job more than once (see `if(isset($this->lead->email_sent) && (bool)$this->lead->email_sent){...`) but it still get inside 5 times anyways.. – benjah Apr 19 '16 at 08:50
  • are you referencing to line number 38 where you check if the attempts are greater than one to avoid continuing? Here you are releasing the job back into the queue so it will continue to try again. If thats the case then it should return $this->delete() because it was already done. Let me know if I am on the right track of what you are referencing. – johnpaulmedina Apr 19 '16 at 15:43
  • I use it because I want to add bit more delay to the job, but if attempts are greater than 1 so it means the job failed at the first attempt isn't it? Because in all the rest of the code if the job passed it should be deleted.. – benjah Apr 19 '16 at 15:53
  • 1
    I think you should move the if($this->attempts() == self::NUMBER_OF_TRIES){ right before the TRY This would allow you to delete the job if the tries are == 5. I see no point in getting down to any of the try catch logic if the number of tries has already exceeded the number of max attempts. You can delete the job once you catch that error. In face it should be the first item in the handle function. Exit if we already attempted too many times. – johnpaulmedina Apr 19 '16 at 16:15
0

I know this is old thread, but when I faced the same problem, it was beacuse I forgot to start the queue with the command php artisan queue:listen. After that, $this->delete worked.

Vasileios Pallas
  • 4,801
  • 4
  • 33
  • 50