Reputation: 10153
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
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
Reputation: 3612
@Kolovious Answer is the correct one, only two notes:
DispatchNewJob
should exists on both Laravel A & B$this->class_to_create
and not $this->$class_to_create
Upvotes: 0
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
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