we're making a web app that's supposed to save the patient's viral signs history in the database, like every two minutes or so in the background. is it possible to do that in laravel if so how can i do it?
I recommend using job:
php artisan make:job PatientViralSignsJob
this command will generate class PatientViralSignsJob in app\Jobs folder.
in the PatientViralSignsJob ... hande() method you could write your logic
public function handle()
{
// write your code here ...
}
finally register your job class in Console\Kernel.php in schedule method:
protected function schedule(Schedule $schedule)
{
$schedule->job(new PatientViralSignsJob())->everyFiveMinutes();
}
this will make your handle method in PatientViralSignsJob executed every five minutes
more details in:
https://laravel.com/docs/7.x/queues#creating-jobs
Related
I have the command, which works like php artisan queue:listen. And it can't work in background in common, but I have to add it to cron tab, but it does not work there. Does it possible to do something like php artisan schedule:run ? The most imortant that when I interrupt this command, all functionalyty will stop. What do I have to do in this situation?
Laravel has his own cron. First of all, you should add Laravel cron to Linux system cron
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
then you can add your commands to Laravel cron.
Laravel crons lives inside a file /app/Console/Kernel.php
the are should be inside function
protected function schedule(Schedule $schedule)
for example
protected function schedule(Schedule $schedule)
{
$schedule->command('emails:send Taylor --force')->cron('* * * * *');
}
But if you want your command run as a system process not as a cron you should use supervisors program(supervisord) or you can create for PHP command file a systemd service file and then run as if the are a normal systemd service and even manage this service through monit program in with web interface as well
If your php script is a process it means that the constructor method of class runs only ones when you start your script and if you red db data in the constructor that data in the script would be stale
Your process script should be process something like this
class OpenOrders extends Command
{
public function __construct()
{
parent::__construct();
}
public function handle()
{
$this->initTicker();
$this->updateBalances();
//the Process
while (true) {
//this is the right place to read DB data
$this->getAllOptions();
$this->openOrders = $this->getOpenOrders();
}
return 0;
}
}
let's me explain example
User click button
run function trigger in Controller
User wait 30sec because MyModel::doSomeThing take long time to process
MyModel::doSomeThing do many thing. I don't want user to wait for it.
Is it possible to run MyModel::doSomeThing by don't care about result and return to user immediately?
function trigger(Request $request){
$id= $request->get('id');
MyModel::doSomeThing($id); // this one take 30 sec.
return response()->json([], 200);
}
If the result of doSomeThing() method isn't necessary for your response & can be done in background, I suggest using Events and Listeners, which will use queues to run in the background, and the user won't need to wait for this procces to finish. The process is fairly simple. Create event and it's listened with these two commands:
php artisan make:event YourEvent
php artisan make:listener YourListener --event=YourEvent
After that, register your event and listener in the App\Providers\EventServiceProvider, under the $listen array:
protected $listen = [
YourEvent::class => [
YourListener::class,
],
];
Now, when you have that sorted out, you need to build your event instance. Inside your newly created method, in the construct method, add this:
public $yourModel;
public function __construct(YourModel $yourModel)
{
$this->yourModel = $yourModel;
}
After you created your model, time to edit your listener, which will hanlde all the logic ghat you need. Inside this handle method, you will have the access to $yourModel instance that we defined in our event:
public function handle(YourEvent $event)
{
// Access your model using $event->yourModel...
YourModel::doSomeThing($event->yourModel);
}
The only thing left do to is to make your listener queueable. You can do this by adding implements ShouldQueue your listened definition:
class YourListener implements ShouldQueue
{
//
}
Now when we have everything setup, you can change your controller code to call this newly created event, and let the queue handle all the logic:
function trigger(Request $request){
$id= $request->get('id');
YourEvent::dispatch($id); //Calling event which will handle all the logic
return response()->json([], 200);
}
And that should be it. I haven't tested this code, so if you encounter any problems, let me know.
I want to submit currunt data in db every minute. For this I am using Cron job from Cpanel with this line.
curl -- silent https link of folloing file
This code is for cron.php (In controller folder)
<?php
class Corn extends Mycontroller {
function __construct(){
parent::__construct();
}
public function index()
{
$insertData['news']=$this->session->userdata('academy')['academy_id'];
$insertData['diyagent_users_id']='1';
$insertData['link']='link';
$insertData['days']='5';
$insertData['to_users']='7';
$insertData['till_date']='01-03-2021';
$this->db->insert('academy_news',$insertData);
}
}
?>
Is it possible to use session here?
When I am calling this file using url inserting data properly, But it's not working using cron job.
please help!
There are many items in the Items table and there is an expired date column in the items table. I just want to get a push notification every day before each items going expire one date before (Expire dates are different to each other and can have one expire date to multuple items). im new to laravel. Please help me.
This can be simply done with Laravel task scheduling
You need to create a custom artisan command like
php artisan make:command SendItemExpiryEmailsToAdmin
Under App\Console\Commands You will find a class SendItemExpiryEmailsToAdmin should be created.
i) First you need to define the signature of the command which will be used to call from the command line.
protected $signature = 'email:send-item-expiry-email-to-admin';
ii) Inside the handle() of the same class, write your logic. A sample logic is given below. You will need to create a Mailable class to send the mail.
public function handle() {
// To fetch all the items ids which are going to expired today.
$itemsIds = Items::whereBetween('expired',
[Carbon::now()->setTime(0,0)->format('Y-m-d H:i:s'),
Carbon::now()->setTime(23,59,59)->format('Y-m-d H:i:s')])
->pluck('id')
->toArray();
$itemsIds = implode(" ", $itemsIds);
Mail::queue(new ItemsExpiryEmail($itemsIds));
// If you are not using queue, just replace `queue` with `send` in above line
}
Mailable to send the mail.
i) Run the following command to create a mailable
php artisan make:mail ItemsExpiryEmail
ii) In the mailable, write your code. A sample code is given below, you can use $this->itemIds in the mail view as it is a public variable.
class ItemsExpiryEmail extends Mailable
{
use Queueable, SerializesModels; // don't forget to import these.
public $itemIds;
public function __construct($itemIds)
{
$this->itemIds = $itemIds;
}
public function build()
{
return $this->view('emails.orders.shipped');
return $this->to('test#example.com', 'Admin')
->subject('Subject of the mail')
->view('emails.adminNotification'); // adminNotification will be the view to be sent out as email body
}
}
This command needs to be executed daily using the Cornjob.
Try this, I'm sure this will help. Let me know if you have any questions.
You can create Task scheduler in Laravel. you can get more info from it's doc here: https://laravel.com/docs/5.8/scheduling
1) you get create login in the scheduling code like. get the all the items which is expiring tomorrow, And send the detail of items to the admin email.
if you have some knowledge in user define artisan command you can also implement scheduling-artisan-commands https://laravel.com/docs/5.8/scheduling#scheduling-artisan-commands.
I have a system where the user can create background tasks via the UI.
The task interval are every few hours (user choice in the UI).
when the user creates a task via the ui i want to add it to the scheduler dynamically.
As the example states, this is static and not dynamic.
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
}
Is it possible? if not, what are the alternatives?
Thanks
I don't see why it wouldn't be possible. The Kernel::schedule method will be run every time php artisan schedule:run is run. If you set it up like the documentation, should be every minute via a cron.
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
With that in mind, I don't see why you can't do something like this:
protected function schedule(Schedule $schedule)
{
// Get all tasks from the database
$tasks = Task::all();
// Go through each task to dynamically set them up.
foreach ($tasks as $task) {
// Use the scheduler to add the task at its desired frequency
$schedule->call(function() use($task) {
// Run your task here
$task->execute();
})->cron($task->frequency);
}
}
Depending on what you store, you can use whatever you like here instead of the CRON method. You might have a string stored in your database that represents one of Laravel's predefined frequencies and in which case you could do something like this:
$frequency = $task->frequency; // everyHour, everyMinute, twiceDaily etc.
$schedule->call(function() {
$task->execute();
})->$frequency();
The main thing to note here, is that the schedule isn't actually scheduling in tasks in the database or in a cron that it manages. Every time the scheduler runs (Every minute) it runs and it determines what to run based on the frequencies you give each task.
Example:
You have a task set up using ->hourly(), that is, to run on the hour, every hour.
At 00:00, the schedule runs, the ->hourly() filter passes, because the time is on the hour, so your task runs.
At 00:01, the schedule runs and but this time the ->hourly() filter fails, so your task does not run.