Laravel: How to run a Library in background (Process component) - laravel

I'm trying to create a program which generates event dates for the whole year. The program works if the user select few events but if the user select 100+ events and assigned them every week it reaches the Maximum execution time error.
In order to fix this, my idea is to run the program in the background.
I'm using Laravel 5.4, running the script below will call the function
$process = new Process('php -f '.$path.' generate_evnt_prepared ' . $content['evntid']);
$process->run();
Function Script
namespace App\Library\shellexec;
use App\Model\V1\EvntPlanDtl;
use App\Model\V1\EvntPlanDtlPrePo;
use Carbon\Carbon;
class RoutePlan {
//put your code here
public function process($method = null, $param = 0)
{
$this->$method($param);
}
I'm pretty sure that the function is called as I'm getting an error in error_logs that the Models are not found
PHP Fatal error: Class 'App\Model\V1\EvntPlanDtl' not found in C:\xampp\htdocs\rdmsoffice\app\Library\shellexec\EventPlan.php on line 30
PHP Stack trace:
PHP 1. {main}() C:\xampp\htdocs\rdmsoffice\app\Library\shellexec\EventPlan.php:0
PHP 2. App\Library\shellexec\EventPlan->process() C:\xampp\htdocs\rdmsoffice\app\Library\shellexec\EventPlan.php:88
PHP 3. App\Library\shellexec\EventPlan->generate_evnt_prepared ()
Anyone knows how to fix this? I'm open to suggestions if this is the wrong way.
Big thanks!

Sounds like a more scalable way is to create a "chunked" version and fire them into a queue for processing. For example, based off some assumptions about the example you provided, I might suggest one firing one queued message for each Event the user selects.
That adds some overhead to manage, but honestly I've always found it's more effective to take some of that cost up front and do it right, rather than finding workarounds like increasing settings or (shudder) shelling out to sub processes.

Related

adonis transformer include. getting 500 error

Inside ScheduleController I call ScheduleTransformer including GroupTransformer. Inside StudentController I call StudentTransformer including GroupTransformer. GroupTransformer availableInclude schedule and students
Once started the server, in postman, I execute:
1-call schedule, return OK, then call student, return error 500.
2-restart server
3-call student, return OK, then call schedule, return error 500.
4-restant server
5-...
error 500: A transformer must be a function or a class extending TransformerAbstract
removing the include in both, no error is shown
Is this error related to some sort of "cross include"?
Windows 10.
I figured out.
A problem or not, here what happens
If transformer A includes B and B includes A, whenever I call one of them, the second start bringing error 500 and the first continue working normally.
the simplest solution is put the importation inside the import, like this:
includeStudents(model) {
const StudentTransformer = use('App/Transformers/StudentTransformer')
return this.collection(model.getRelated('students'), StudentTransformer)
}
instead of up in the top of, as it is usual.

Laravel - OutputStyle from jobs

I'm running into issues with allowing a Laravel job to interact with the console output.
At the moment I am passing in the OutputStyle from a Command to the Job constructor and assigning it.
I have seen the InteractsWithIO trait but if I use that by itself without assigning the OutputStyle from the command then it says it is null.
Call to a member function title() on null
I have also tried setting $this->output from the container using
$this->output = resolve(OutputStyle::class);
This fails with a
Target [Symfony\Component\Console\Input\InputInterface] is not instantiable while building [Illuminate\Console\OutputStyle].
I've also ran into issues with PHPUnit tests that run through this job. The output from the class is displayed in the test output.
.......................Processing element 1 for "Section"
.......
What's the best way to handle outputting to the console within Laravel that also works with PHPUnit?
Putting the following code in a Service Provider works:
$this->app->bind('console.output', function () {
return new OutputStyle(
new StringInput(''),
new StreamOutput(fopen('php://stdout', 'w'))
);
});
I am then able to say, in my Job,
$this->output = resolve('console.output');
Which gives access to all the methods such as title, section, and table.

How to have usefull debugging or error messages from laravel

I'm a bit new to laravel, but I'm experienced in Php.
In previous works, I set a mecanism that allowed me to be informed when nearly any problem occurred on the server:
I got full stack
precise PHP error messages
for nearly all king of errors
a mail sent to me
So when I began to work with laravel, I tried to do the same things, and achieved:
full stack
a mail sent to me
But I can't have meaningful error in all case. One example:
$store = Store::create(...)
In this line I forget to specify the namespace (\App\Store::create), and I get those error messages:
first:
FatalThrowableError ; Type error: Argument 1 passed to App\Http\Controllers\User::create() must be an instance of Illuminate\Http\Request, array given, called in /var/www/html/laravel/blog/app/Http/Controllers/User.php on line 94
second:
ErrorException ; Trying to get property of non-object in VerifyCsrfToken.php (line 156)
third:
FatalThrowableError ; Type error: Argument 1 passed to Illuminate\Session\Middleware\StartSession::addCookieToResponse() must be an instance of Symfony\Component\HttpFoundation\Response, array given, called in /var/www/html/laravel/blog/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php on line 72
I understand that laravel is a complex framework but I can't figure why it produces this errors, and how I can have more useful errors (as as it is I can only know that "something is bad").
Has someone an idea ?
¹ There is some errors that Php prefers to keep to himself (in its logs) :-)
When you start a new Laravel project, error and exception handling is
already configured for you. The App\Exceptions\Handler class is where
all exceptions triggered by your application are logged and then
rendered back to the user.
https://laravel.com/docs/5.4/errors
I recommend you to dive into the official docs and into your App\Exceptions\Handler.
Maybe you are looking for report and render methods in that class.
I finally cornered the problem and I learned a lot.
I thank for their benevolence #Don't Panic and #Vitalmax !
The error was that I forgot that PHP namespaces are case insensitive: in my post I cleaned a bit the code as I knew that it didn't stick to the code's conventions (a controller's name must begin with a capital letter). Originally my controller name was user and the faulty code was:
$user = User::create(...)
As you can guess PHP believed that I wanted to call user::create (as I have such a method in my controller) and not User::create (as I wanted).
What I learned:
don't alter the code when asking for help
Laravel use a cache system that can get in the way of the debugging (see a question that I asked on laracast's forum )
take more time to read the error message; I know this rule but I keep doing otherwise

Executing Artisan command with arguments

Currently i'm facing following problem:
I want to update my search index automatically after my database has been updated.
I've registered a saved() listener on my tables in AppServiceProvider:
\App\Customer::saved(function(\App\Customer $customer) {
// Update search index here
});
Inside the closure i try to call an Artisan command (scout:import) passing App\\Customer to the command. I've tried
Artisan::queue('scout:import', ['' => 'App\\\Customer']);
// Fails with message: Uninitialized string offset: 0
Artisan::queue('scout:import', ['model' => 'App\\\Customer']);
// Fails: Cannot redeclare class App\Customer
Artisan::queue('scout:import', ['App\\\Customer']);
// Fails: Not enough arguments (missing: "model")
I did'nt find information where to put the required arguments in the offical documentation.
I'm sure that it's dead simple (like everything in laravel) but i'm not able to get it done ...
The correct format is:
Artisan::queue('email:send', [
'user' => 1, '--queue' => 'default'
]);
As per: https://laravel.com/docs/5.3/artisan#programmatically-executing-commands
I'd say your middle example is probably closest, and is executing the command with the correct parameters, but there is something else going on under the surface.
EDIT
Just did a bit more digging, you need to refer to the signature of the Console command, which isn't actually apparent on the surface. In your case, you need to refer to this console command:
https://github.com/laravel/scout/blob/2.0/src/Console/ImportCommand.php
Note the signature is marked with {model}.
So your command would look like:
Artisan::queue('scout:import', ['model' => 'App\\\Customer']);
Another example using the controller make command, note that this time we using the signature segment {name}:
Artisan::call('make:controller', ['name'=>'FOOBAR']);
Again, there is probably an underlying issue here - you should try running the import command from the console/terminal directly to see if you get the same issue.
Try this:
\App\Customer::saved(function(\App\Customer $customer, $input) {
// Update search index here
});
Artisan::queue('scout:import {input}', ['App\\\Customer']);
You don't need to sync with algolia using an artisan call.
Refer to algolia documentation:
Algolia Laravel Doc
'Every time you modify a model, Laravel emits an event. Scout is listening for that event, informing your app to make an HTTP call to Algolia to update its index.
You don’t have anything else to do, use your searchable class the way you usually would do'

insertNewChild is not a function in DHTML Tree grid Pro

I want to access child data from server when we append parent. Now I am using
mygrid.attachEvent("onOpenStart", getSubElements );
When I am using getSubElements, this method then it is showing an error: inserNewChild is not a function.
I am using this line, please review this and let me know where I am doing wrong.
mygrid.insertNewChild("a0J9000000TTdLtEAL","a0J9000000TTdKz","CLASS.000010",0,0,0,0,"");
Please note that the insertNewChild() is the method of the dhtmlxTree, and won't work in dhtmlxTreegrid.
http://docs.dhtmlx.com/api__dhtmlxtree_insertnewchild.html
You may use the addRow() method:
http://docs.dhtmlx.com/api__link__dhtmlxtreegrid_addrow.html
Also please try to use the onOpenEnd event instead of onOpenStart:
http://docs.dhtmlx.com/api__dhtmlxtreegrid_onopenend_event.html

Resources