简体   繁体   中英

Issues using the Laravel Queue system

I have been struggling with this all evening now. I am in the process of implementing a system whereby reports that are requested by users are queued and sent at a later time. I am using the native Laravel solution however whenever I move from sync to database I start getting errors. I have looked at the laravel debug log and can see that for some reason whenever I use database I am getting "trying to get property of non object" errors.

[2018-02-11 12:05:46] production.ERROR: ErrorException: Trying to get property of non-object in /var/www/appname/app/Libraries/InstagramEngine.php:143

Stack trace:

#0 /var/www/appname/app/Libraries/InstagramEngine.php(143): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Trying to get p...', '/var/www/app...', 143, Array)

#1 appname/app/Jobs/ProcessCollectionReport.php(81): App\\Libraries\\InstagramEngine::getAccountMediaByUserId(Object(App\\Models\\Account), 1515715200, 1518393599)

My code is below - I shall start with the controller which is very straight forward:

/**
 * Builds excel report for collection
 * @param         $slug
 * @param Request $request
 */
public function export(Request $request, $slug)
{
    // get logged in user
    $user = User::find(Auth::user()->id);

    // get collection
    $collection = Collection::where('slug', $slug)->firstOrFail();

    // get start and end date
    $start = $request->input('start', Carbon::now()->subDays(30)->startOfDay()->timestamp);
    $end   = $request->input('end', Carbon::now()->endOfDay()->timestamp);

    // queue the job
    ProcessCollectionReport::dispatch($user->id, $collection->id, $start, $end);
}

As you can see my controller literally takes a few details and created a queued item based on it. I have even created the item using just IDs incase of serialisation issues with Laravel (I originally thought this may be causing my problems but they have remained even using just this codebase)

My jobs class is below

<?php

namespace App\Jobs;

use App\Notifications\CollectionReportGenerated;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

use App\Models\User;
use App\Models\Collection;
use App\Libraries\InstagramEngine;
use App\Libraries\Profile;
use Excel;

class ProcessCollectionReport implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $userId;
    protected $collectionId;
    protected $start;
    protected $end;

    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public $tries = 5;

    /**
     * The number of seconds the job can run before timing out.
     *
     * @var int
     */
    public $timeout = 210;

    /**
     * Create job instance
     * ProcessCollectionReport constructor.
     * @param User       $userId
     * @param Collection $collectionId
     * @param            $start
     * @param            $end
     */
    public function __construct($userId, $collectionId, $start, $end)
    {
        // access arguments
        $this->userId          = $userId;
        $this->collectionId    = $collectionId;
        $this->start           = $start;
        $this->end             = $end;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // set base profiles
        $profiles = new \stdClass();
        $profiles->ranges = dateRanges($this->start, $this->end);
        $profiles->accounts = array();

        // get collection
        $collection = Collection::find($this->collectionId);
        $user       = User::find($this->userId);

        // loop through accounts in collection
        foreach($collection->accounts as $account)
        {
            // create new profile instance
            $profile = new Profile($this->start, $this->end);

            // gets media for account
            $media = InstagramEngine::getAccountMediaByUserId($account, $this->start, $this->end);
}
}
}

Now as you can see, from within my job I make an external call to a class + function getAccountMediaByUserId - this class accepts as its first parameter an account model however from the error above it looks like it is being passed the whole array containing all of the models. The code for the function is below:

/**
     * Returns account media within specified range for Instagram Account by ID
     * @param Account $account
     * @param $start
     * @param $end
     * @return array
     */
    public static function getAccountMediaByUserId(Account $account, $start, $end)
    {
        // set up unique cached key for API call
        $cache_key = sha1($account->username.$start.$end);

        // check if we have this API call cached
        if(Cache::has($cache_key))
        {
            // return results
            return Cache::get($cache_key);
        }

        // set up default response
        $return = array();

        // set breaker to false
        $breaker = false;
        $page = 1;

        // set initial URL for API call
        $url = 'https://api.instagram.com/v1/users/'.$account->instagram_id.'/media/recent/?count=30&access_token='.Auth::user()->primaryAccount->access_token;
}

What really puzzles me is that if the cache is set than the code works which is odd because if I am passing the whole array then why does $account->username work but not $account->Instagram_id

And I really don't understand why any of this only happens when I'm using database not sync.

Thanks so much in advance

Solved:

I was using auth::user in my job which isn't available when being ran as a job

Thanks

Daniel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM