Ewan Valentine
Ewan Valentine

Reputation: 3931

Laravel queue listener from external service

I have a legacy API written in Laravel, and I'm attempting to post data to it from a RabbitMQ queue. I'm using a third party library to integrate RabbitMQ into the native Laravel Queue architecture. Which works well, and is handling messages correctly when the listener console command is running.

However, when I pass the following event, including the job and data keys, which are required by the queue handler...

{"job":"SixtyFiveContrib\\Jobs\\CreateSubmissionMetaDataJob@handle","data":{"title":"","story":"Testing 123","author":"Ewan Valentine","email":"","address":"","dob":"","phone":"","site":"The Lad Bible","legal":"The LAD bible - Facebook","agreed":false,"signature":"","files":[{"filename":"test.png","filesize":0,"filetype":""}],"agreement":{"id":"","facebook_id":""},"attempts":1036}}

I notice the class which handles queued events, splits the class path and the method name (SixtyFiveContrib\Jobs\CreateSubmissionMetaDataJob and handle), and attempts to call that class from the container.

However jobs aren't automatically part of the container. When I attempt to add the job into the container myself, I run into a situation where I can't dynamically pass the 'data' from the queue into the job, for example...

$this->app->bind(\SixtyFiveContrib\Jobs\CreateSubmissionMetaDataJob::class, function() {
    return \SixtyFiveContrib\Jobs\CreateSubmissionMetaDataJob(????);
});

If I omit this entry from the container, the queue handler can no longer resolve the job, I get the following error...

[Illuminate\Contracts\Container\BindingResolutionException]
Unresolvable dependency resolving [Parameter #0 [ $data ]] in class SixtyFiveContrib\Jobs\CreateSubmissionMetaDataJob

Here's my job class (sensitive business logic omitted).

<?php

namespace SixtyFiveContrib\Jobs;

use App;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

use SixtyFiveContrib\Jobs\Job;

/**
 * CreateSubmissionsMetaDataJob
 *
 * @author    Ewan Valentine <[email protected]>
 * @copyright The LAD bible Group - 2016
 */
class CreateSubmissionMetaDataJob extends Job implements SelfHandling 
{
    use InteractsWithQueue, SerializesModels;

    /**
     * @var array $data
     */
    public $data;

    /**
     * __construct
     *
     * @param array $this->data
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    public function handle() 
    {
        try {

            // Omitted 
        } catch (\Exception $e) {
            \Log::error($e->getMessage() . " " . $e->getLine());
            return $e->getMessage(); 
        }
    }
}

Upvotes: 3

Views: 1924

Answers (1)

Ewan Valentine
Ewan Valentine

Reputation: 3931

Okay, I figured it out! You have to pass your data as a second param to your handle or fire method, first argument is the application instance.

<?php

namespace SixtyFiveContrib\Jobs;

use App;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

use SixtyFiveContrib\Jobs\Job;

/**
 * CreateSubmissionsMetaDataJob
 *
 * @author    Ewan Valentine <[email protected]>
 * @copyright The LAD bible Group - 2016
 */
class CreateSubmissionMetaDataJob extends Job implements SelfHandling 
{
    use InteractsWithQueue, SerializesModels;

    /**
     * @var array $data
     */
    public $data;

    /**
     * __construct
     */
    public function __construct()
    {
    }

    public function handle($app, array $data) 
    {
        try {

            // Omitted 
        } catch (\Exception $e) {
            \Log::error($e->getMessage() . " " . $e->getLine());
            return $e->getMessage(); 
        }
    }
}

Upvotes: 2

Related Questions