Maybe I'm not understanding on Laravel queue works, or maybe it itself is not working, my expected behaviour for Laravel Queue/Dispatch is that if a dispatch is initiated from the Controller, the code dispatched to queue should be executed silently and in the background. The end-user browser should not have to wait for the code to execute.
This is however what happens with my code, the dispatched code to queue leaves the browsers "Spinning..." whilst is executes.
Is this expected behavior? The code:
**Controller:**
public function make_eps_certs($tbl_eps)
{
//dd(Carbon::now()->addMinutes(10))
Log::info('Dispatching maeEPSCert to Queue');
$var_result=makeEPSCerts::dispatch($tbl_eps)->onQueue('eventadmin')
->delay(10);
return redirect()->back();
}
**Job:**
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\partSubs;
use Log;
use Image;
class makeEPSCerts implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
protected $passdata;
public $timeout = 120;
public function __construct($passdata)
{
Log::info('Constructing makeEPSCert');
$this->passdata = $passdata;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
try
{
Log::info('Beginning makeEPSCert');
$tbl_eps=$this->passdata;
.....
Change your LOG_DRIVERin your .env to database and create the needed migration files with php artisan queue:table, after that do a php artisan migrate.
After that you just need to run php artisan queue:work --queue="eventadmin"
and then you will recognize the expected behavior
A more detailed documentation can be found here: https://laravel.com/docs/5.5/queues
You can try again in the following way (I assume that you did instructions in Laravel docs but someday it's not working):
Step 1: drop table 'jobs' in your database.
Step 2: run command 'php artisan migrate' in console to create table 'jobs' again.
Step 3: run command 'php artisan queue:work' in console
Step 4: retry your app
Note that in .env file, you set up:
QUEUE_CONNECTION=database
QUEUE_DRIVER=database
P/s: It works for me!
Related
Is there a way to disable artisan commands from running at all?
For example, if I wanted to disable php artisan migrate:fresh from running, where would I go to remove/disable the command?
As far as I know, laravel does not have this feature by default. And this is still under laravel ideas.
I also had this problem before and could not find a solution, I am not sure why you want to disable a command. But my case was that in the production environment I never want to run php artisan migrate:fresh. So what I end up with is to override the default command.
For example, in the routes/console.php file:
if ('production' === App::environment()) {
Artisan::command('migrate:fresh', function () {
$this->comment('You are not allowed to do this in production!');
})->describe('Override default command in production.');
}
So, when you are in production, php artisan migrate:fresh will do nothing. You can change the condition based on your requirement, my example is just an idea of how you can override a laravel default command based on some variables in the .env file.
You can do a lot of things here as well, I am not sure why you want to disable the command, so this is the best I can help.
Create a command like the following
<?php
namespace App\Console\Commands\Utils;
use Illuminate\Console\Command;
use Illuminate\Console\Events\CommandStarting;
class PreCommand extends Command
{
protected $signature = 'precommand';
public function handle(CommandStarting $event) {
if (app()->environment(['production'])) {
logger('Trying to fresh database in production');
if ($event->command == 'migrate:fresh') {
$this->output = $event->output;
$this->info('You can not fresh database in the production');
die();
}
}
}
}
And register it in your EventServiceProvider's boot method
<?php
namespace App\Providers;
use App\Console\Commands\Utils\PreCommand;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Console\Events\CommandStarting;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
/**
* Register any events for your application.
*
* #return void
*/
public function boot() {
Event::listen(CommandStarting::class, PreCommand::class);
}
}
trying to prevent queued job from passing by ViewComposer in laravel using pm2.
Problem : setCookie has not been applied because (i think ) there is no session from extern calls access (pm2).
let me explain:
also sharing with you this part of my app.
I have a queued job that sends dynamic emails (templates and mail params)
in my ServiceController,
also, am sharing needed data with all view when returning to any of them,
so I created a ViewComposer called by any view(*) in AppServiceProvider, inside this ViewComposer, am using a trait that uses many traits too, to collect data I need for views.
when I navigate in my application everything looks fine.
when implementing any task that uses queued jobs, in my case sending an email:
when I run php artisan queue:work everything works fine too and I receive emails.
BUT
when I use pm2 deamon which calls that queue it fires an exception :
(setCookie has not been applied) related to that trait I use in view composer.
I know it's hard for me to explain it, but I really need some help here.
here is my code :
pm2 path : / (server root)
app path :/prod
shared hosting with ssh.
1. AppServiceProvider
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
Schema::defaultStringLength(191);
}
public function boot()
{
view()->composer('*',
'App\Http\ViewComposers\MasterComposer');
}
}
2. WebsiteComposer:
namespace App\Http\ViewComposers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use App\Website;
use other_traits;
trait WebsiteComposer
{
use other_traits;
protected function Get_Website(Request $request)
{
//some code by calling other traits;
// $results= get client websitestuff;
$this->website= $results;
}
}
3. MasterComposer:
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use Illuminate\Http\Request;
class MasterComposer
{
use WebsiteComposer;
public $web=[];
public function __construct()
{
}
public function compose(View $view)
{
//to prevent external views( email templates located in
//views/emails from passing by getting website process...
if(!starts_with($view->getName(), 'emails'))
{
//here where exception fired using pm2
$this->Get_Website(request());
$this->web=$this->website;
}
View::share('website', $this->web);
}
}
4. ServiceContorller:
(the Start of the process)
// POST PROCESS then Calling this function :
public function EmailDispatcher($data,Request $request)
{
//some code...
dispatch(function () use ($data) {
dispatch(new GuestMailerJob($data));
});
return redirect('somview');
}
5. GuestMailerJob:
namespace App\Jobs;
use App\Mail\GuestMailer;
// needed uses...
class GuestMailerJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable,
SerializesModels,GuestMailer;
protected $data;
public $tries = 3;
public $timeout = 10;
public function retryUntil()
{
return now()->addSeconds(12);
}
public function __construct(Array $data)
{
$this->data=$data;
}
public function handle()
{
$this->sendEmail($this->data);
}
}
6. GuestMailer:
namespace App\Mail;
use Illuminate\Http\Request;
use Mail;
trait GuestMailer
{
protected function sendEmail(array $all)
{
$toview = array(
'title' => $all["title"],
'other_attributes' => $all["other_attributes"]
);
Mail::send( [$all["template"]=> $all['view']],$toview,
function ($message) use($all)
{
$message->from( $all['from'],$all['nameFrom'] );
$message->subject( $all['subject'] );
//other params...
}
});
}
}
7. pm2 executed file : mail-worker.yml
//located in: (/prod)
//mail-worker.yml content:
apps:
- name: mail-worker
script: artisan
exec_mode: fork
interpreter: php
instances: 1
args:
- queue:work
- --tries=1
- --sleep=1
8 : artisan Cleaning
all php artisan cleaners are implemented
ex : php artisan clear-compiled
php artisan queue:restart
9 : pm2 Configuration :
pm2 start mail-worker.yml
pm2 monit
10 - pm2 state :
id name mode reload status cpu memory
0 mail-worker fork 1 online 0% 6.5mp
it's working with php artisan queue:work / listen
but with pm2 here is the exception.
pm2 Result :
Whoops\Run::handleError("Trait method setCookie has not been applied,
/app_base_path/PRODMAAN/vendor/filp/whoops/src/Whoops/Run.ph x
Whoops\Run::handleShutdown() [internal]:0
failed_Jobs result :
Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\GuestMailerJob has been attempted too many times or run too long. The job may have previously timed out.
what is the problem ?
thank you for any advice about the code structure too.
I tried to get a simple job running exactly like the example in the Laravel Documentation - https://laravel.com/docs/5.2/queues#writing-job-classes - but I get this error: "No handler registered for command [App\Jobs\SendReminderEmail]".
I followed the instructions to make the jobs table and even the failed_jobs table and have the exact example code.
I assured that the handle() function is there so I don't know what else can be missing.
Regards.
Update with code:
First I used the class in the Laravel example but then I simplified it to this:
<?php
namespace App\Jobs;
use App\Jobs\Job;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SyncFromJson extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
//
$var = "fooooo";
\Log::info("job is running!!!", $var);
}
}
To call the job I created a simple method in a controller that dispatches the job:
$job = (new SyncFromJson())->delay(3);
$this->dispatch($job);
Also tried this:
$this->dispatch(new SyncFromJson());
For what it's worth, I was having a similar problem and implementing 'SelfHandling' seems to have fixed the issue.
Try changing this:
class SyncFromJson extends Job implements ShouldQueue
To this:
class SyncFromJson extends Job implements ShouldQueue, SelfHandling
I had the exact same problem. In my case it turned out it was the incorrect provider in app config that was the problem. I used a previous project as a framework for my new project and inherited the Laravel collective bus package (That was not required.) The moment I removed the collective bus package ( laravelcollective/bus ) , ran composer update and replaced
Collective\Bus\BusServiceProvider::class,
with
Illuminate\Bus\BusServiceProvider::class,
everything worked fine. This may be a similar issue?
I'm using Laravel 5.0 and I've created a queued command with the Artisan CLI:
php artisan make:command SendEmail --queued
I need to use the DB::table() query builder method into this command, but I'm not able to make it work.
This is an excerpt of my code:
<?php namespace App\Commands;
use App\Commands\Command;
use DB;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldBeQueued;
class SendEmail extends Command implements SelfHandling, ShouldBeQueued {
use InteractsWithQueue, SerializesModels;
protected $message;
public function __construct($message)
{
$this->message = $message;
}
public function handle()
{
$data = DB::table('structures')->where('id', '=', '1')->first();
// $data is always empty even if database connection works outside the command!!! <-------------------
// no error exception is thrown
}
}
What am I doing wrong?
I found the error. I had to restart the supervisor queue in order the code to be correctly re-read:
supervisorctl
supervisor> restart myQueue
I'm trying to use getstream.io in my Laravel 5 application. I'm following the tutorial here, but got stuck on this one:
$feed = FeedManager::getUserFeed($user->id);
When I go to the FeedManager class, I couldn't find the getUserFeed() method. Here's how my FeedManager class look like:
<?php namespace GetStream\StreamLaravel\Facades;
use Illuminate\Support\Facades\Facade;
class FeedManager extends Facade {
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor() { return 'feed_manager'; }
}
I wonder if I did something wrong during installation. The tutorial said to run php artisan config:publish get-stream/stream-laravel, but I did php artisan vendor:publish get-stream/stream-laravel. The reason is because I got an error when running config:publish, so I used vendor:publish instead
The Stream-PHP-Example is now working in Laravel 5, take a look: https://github.com/GetStream/Stream-Example-PHP