Nick
Nick

Reputation: 10153

Laravel. Common queue for two projects

I have two different projects. Laravel project A and Laravel project B. And I need create task from Project A to project B through queue. And I dont want create Job for this in Project A.

Currently my realisation is:

Project A

Job with state but without business logic:

<?php

namespace App\Jobs;

use ...;

/**
 * Fake class!!!
 */
class MyJob extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    public $queue = 'MyQueue';

    /**
     * Some state
     */
    protected $_contentId;

    public function __construct($contentId)
    {
        $this->_contentId = $contentId;
    }

    /**
     * Excess. I dont need business logic in project A.
     */
    public function handle()
    {
    }
}

And I push job into queue in Project A:

    ...
    $this->dispatch(
        new MyJob($this->_contentId)
    );
    ...

Project B

<?php

namespace App\Jobs;

use ...;

/**
 * Really needed class
 */
class MyJob extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    public $queue = 'MyQueue';

    /**
     * Some state
     */
    protected $_contentId;

    public function __construct($contentId)
    {
        $this->_contentId = $contentId;
    }

    /**
     * Here is my business logic. In Project B!
     */
    public function handle()
    {
        Artisan::call('my_command', [
            'id' => $this->_contentId,
        ]);
    }
}

So, how to do without MyJob in Project A?

Upvotes: 3

Views: 2997

Answers (4)

Kolovious
Kolovious

Reputation: 71

if you connect both laravels apps to a same queue server. you can put jobs on the other site queue. For example, if you are in Laravel A

$job = (new Job())->onQueue('theQueueForLaravelB')
dispatch($job);

But to complete this, you should make a basic job that dispach a new one with parameter data. Like:

class DispatchNewJob implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    private $class_to_create;
    private $data;

    public function __construct($class_to_create, $data)
    {
        $this->class_to_create = $class_to_create;
        $this->data = $data;
    }

    public function handle()
    {
        dispatch(new $this->class_to_create($this->data));
    }
}

So, you can now dispatch any job from laravel A, to laravel B with any data.

You can call

$job = (new DispatchNewJob('App\Jobs\JobInLaravelB', ['data'=>'myawesomedata'])
               ->onQueue('LaravelBQueue');
dispatch($job);

Sorry for my english, i'm from Argentina.

Upvotes: 7

Broshi
Broshi

Reputation: 3612

@Kolovious Answer is the correct one, only two notes:

  1. DispatchNewJob should exists on both Laravel A & B
  2. There's a typo, it should be $this->class_to_create and not $this->$class_to_create

Upvotes: 0

mils
mils

Reputation: 1916

How about this (it's a total hack though), create a composer project that contains a bunch of Job classes and a bunch of job-handler classes, for example:

<?php

namespace Jobs;

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

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

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        JobType1Handler::handle();
    }
}

class JobType1Handler
{
    public static function handle()
    {

    }
}

and then modify the handler code in your Project B . So you would be modifying the source in your /vendors folder, which would make deployment difficult.

Upvotes: 2

Denis Mysenko
Denis Mysenko

Reputation: 6534

Laravel expects both ends (dispatcher and listener) to run the same application - so that serializations and deserializations work correctly.

Out of box, Laravel (or Lumen) doesn't support plain queue messages so that receiving end may run a different application or framework.

If you use SQS for queues, my custom SQS connector can help you. Otherwise, you would have to write one yourself.

Upvotes: 2

Related Questions