Laravel Queue using Beanstalkd Failing - php

I've tried to using queue for everytime user register and send an email to them to verify.
I'm doing it successfully using Laravel 5.1
I just wandering how can I can stop current queue if I got an error and then when I fix it I restart the job from the last queue?.
How about the error like this:
[InvalidArgumentException]
View [emails.versify_email] not found.
[InvalidArgumentException]
View [emails.versify_email] not found.
[InvalidArgumentException]
View [emails.versify_email] not found.
I've tried at homestead using:
public function failed(){
//I've tried send email but it not sending
}
or at AppServiceProvider
Queue::failing(function ($connection, $job, $data) {
$user ='mymail#gmail.com';
Mail::send('emails.fail_queue', ['user' => $user], function ($m) use ($user) {
$m->subject('Failing:' . $user)
->to($user);
});
});
None of the them is working.
what should i do if its like that when happened at production?.

When an exception is thrown from the handler Laravel tries to release the job back to the queue unless it is explicitly deleted.
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Queue/Worker.php#L198-L227
You can use the $delay parameter to put back in the queue with delay. Or better just bury the job yourself, if you are able to detect the issue.
$this->job->bury()

Related

Releasing AWS SQS Message back to queue from Laravel/Lumen

I'm using Lumen (Laravel) to handle an AWS SQS queue with the sqs-plain driver for the connection. That driver works the same way as the default sqs driver but allows me to use custom JSON in the queue message body.
Based on that package I've created a job handler that works fine, but I'm having trouble understanding how to properly release a message back to the queue.
In the handler method I've injected a SqsJob and tried calling the release method which isn't working as I'd expect.
It seems that the method SqsJob::release calls changeMessageVisibility on the SQS API and the parent release method, which simply sets a class variable $this->released = true; on the job.
So the "releasing" of the message isn't really done, as much as the message is just being marked as released and the visibility of the message in the queue is changed. Not handling the release would result in the message being "handled" and deleted from the queue.
By trial and error I found out, that throwing an exception in the handler method sends the message back to the queue.
Here's a simplified version of the job handler:
namespace App\Jobs;
use Illuminate\Contracts\Queue\Job as LaravelJob;
use Illuminate\Queue\Jobs\SqsJob;
use Illuminate\Support\Facades\Log;
class HandlerJob extends Job
{
protected $data;
/**
* #param SqsJob $job
* #param array $data
*/
public function handle(SqsJob $job, array $data)
{
if ($this->validData($data)) {
// handle the job
} else {
$this->release(60);
// actually release the job back to queue
throw new \Exception('Invalid Data');
}
}
private function validData($data)
{
//not relevant
}
}
This seems like a basic task to be handled by the queue worker but I can't figure it out.
What is the proper way of releasing a message back into the the queue using the Laravel/Lumen framework?

Conditional subscription to listener in Laravel

I have set up a listener by adding it in EventServiceProvider
protected $subscribe = [
MyListener::class
];
The listener (MyListener) has a subscribe function that subscribes to the events the listener wants to listen for - and it works fine.
Now, I'm trying to add a check to restrict which events should be listened to. Something like
public function subscribe($events)
{
$config = ConfigService::getUserConfig();
if ($config->shouldSubscribe) {
$events->listen(.....);
}
}
I'm having some issues after adding this logic however.
It seems that when running composer install it executes the subscribe method.
This causes an issue, because there is no active session when running composer install - so I'm met with a SQL error - it can't find which database to search for configuration in - followed by this error
Script #php artisan package:discover handling the post-autoload-dump event returned with error code 1
How can I conditionally subscribe to certain events in the listener?
It is not the exact response for your answer, but it should work in your case. You can detect if your code is running from console by using Application::runningInConsole() function.
Example:
public function subscribe($events)
{
// Running from cli script, abort ship!
if(app()->runningInConsole())
{
return;
}
$config = ConfigService::getUserConfig();
if ($config->shouldSubscribe) {
$events->listen(.....);
}
}

Laravel queue keep processing multiple times for a job

Below is what's happening when i run php artisan queue:listen and at my job table only have one job
and this is my code :
public function handle(Xero $xero)
{
$this->getAndCreateXeroSnapshotID();
$this->importInvoices($xero);
$this->importBankTransaction($xero);
$this->importBankStatement($xero);
$this->importBalanceSheet($xero);
$this->importProfitAndLoss($xero);
}
In order for a job to leave the queue, it must reach the end of the handle function -- without errors and exceptions.
There must be something breaking inside one or more of your functions.
If an exception is thrown while the job is being processed, the job will automatically be released back onto the queue so it may be attempted again. https://laravel.com/docs/5.8/queues
The same behavior can be achieved with
$this->release()
If you can't figure out what is breaking, you can set your job to run only once. If an error is thrown, the job will be considered failed and will be put in the failed jobs queue.
The maximum number of attempts is defined by the --tries switch used
on the queue:work Artisan command. https://laravel.com/docs/5.8/queues
php artisan queue:work --tries=1
If you are using the database queue, (awesome for debugging) run this command to create the failed queue table
php artisan queue:failed
Finally, to find out what is wrong with your code. You can catch and log the error.
public function handle(Xero $xero)
{
try{
$this->getAndCreateXeroSnapshotID();
$this->importInvoices($xero);
$this->importBankTransaction($xero);
$this->importBankStatement($xero);
$this->importBalanceSheet($xero);
$this->importProfitAndLoss($xero);
}catch(\Exception $e){
Log::error($e->getMessage());
}
}
You could also set your error log channel to be slack, bugsnag or whatever. Just be sure to check it. Please don't be offended, it's normal to screw up when dealing with laravel queues. How do you think I got here?
Laravel try to run the job again and again.
php artisan queue:work --tries=3
Upper command will only try to run the jobs 3 times.
Hope this helps
In my case the problem was the payload, I've created the variable private, but it needs to by protected.
class EventJob implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
// payload
protected $command;
// Maximum tries of this event
public $tries = 5;
public function __construct(CommandInterface $command)
{
$this->command = $command;
}
public function handle()
{
$event = I_Event::create([
'event_type_id' => $command->getEventTypeId(),
'sender_url' => $command->getSenderUrl(),
'sender_ip' => $command->getSenderIp()
]);
return $event;
}
}
The solution that worked for me to delete the job after pushing them into the queue.
Consider the e.g.
class SomeController extends Controller{
public function uploadProductCsv(){
//process file here and push the code inot Queue
Queue::push('SomeController#processFile', $someDataArray);
}
public function processFile($job, $data){
//logic to process the data
$job->delete(); //after complete the process delete the job
}
}
Note: This is implemented for laravel 4.2

Laravel - Stripe - Ultrahook - Webhook are not caught

I'm using Laravel 5.4 and Laravel Cashier. I would like to be able to catch Stripe webhooks in my localhost:8888
To do so I installed ultrahook and I started it like this
Ultrahook
http://stripe.leococo.ultrahook.com -> http://localhost:8888/stripe/webhook
Laravel routes
Route::post('stripe/webhook', '\Laravel\Cashier\Http\Controllers\WebhookController#handleWebhook');
Stripe Webhook configuration
http://stripe.leococo.ultrahook.com
Problem
When I send a webhook from Stripe I get Test webhook sent successfully
In the terminal ultrahook I get this
[2017-05-31 19:26:04] POST http://localhost:8888/stripe/webhook - 200
But it seems the handleWebhook function is not triggered. It does not stop on a break point neither die('test')
I tried php artisan route:clear php artisan config:clear. I don't know wether it is normal or not, but I do not see anything in the network section in the Chrome Inspector
Add the following line in your .env
CASHIER_ENV=testing
Laravel/Cashier checks if your call to the webhook has a valid event id.
To verify this, eventExistsOnStripe calls back stripe servers with this event id to check its existence.
Here is the main webhook entry point from Laravel/Cashier 7.0:
public function handleWebhook(Request $request)
{
$payload = json_decode($request->getContent(), true);
if (! $this->isInTestingEnvironment() && ! $this->eventExistsOnStripe($payload['id'])) {
return;
}
$method = 'handle'.studly_case(str_replace('.', '_', $payload['type']));
if (method_exists($this, $method)) {
return $this->{$method}($payload);
} else {
return $this->missingMethod();
}
}
isInTestingEnvironment just check whether we are in a testing environnment or not : Thank you Cpt Obvious :)
protected function isInTestingEnvironment()
{
return getenv('CASHIER_ENV') === 'testing';
}

Laravel: Load a page and then send a mail

i am trying to load page first and then activate the $mailer to send email. because when i click on to go to next page its taking time, because its sending emails and then it is loading so,
what is the best way to do it. or any way. because i cant figure it out.
here is snippet
public function sInterest($project_id, AppMailer $mailer)
{
$project = Project::findOrFail($project_id);
if($project->investment){
$mailer->sendInterestNotificationI($user, $project);
$mailer->sendInterestNotificationD($project, $user);
$mailer->sendInterestNotificationA($project, $user);
return view('projects.offer', compact('project'));
}
}
is there a way $mailer to activate after returning a page?
In your AppMailer sendInterestNotification*() methods, replace sync email delivery with queued email delivery (see Queueing Mail in Laravel documentation)
Then page will be returned instantly, emails will be put in the corresponding queue. You will have to edit .env file to change the QUEUE driver and to start a queue listener as a separate process, detailed documentation is given on Laravel website
There is no way you can return a page to browser and then run some extra commands in your controller.

Categories