I have an API REST built using Laravel 5.8 framework.
I have to get the data for my app from a public REST API. For this, i have to do a lot of requests. I made a seeder what do this, and it takes 2 minutes for the entire migration data process approximately (take from the public Api and insert in my application database).
I cant run the seeder by a cronjob because it does not work (it looks like need an user to execute the command to work). So, i created a job class what i call from my kernel file, the queue configuration was seted as database (QUEUE_CONNECTION=database
), like a scheduled task (to execute with Supervisor: https://laravel.com/docs/5.8/queues#supervisor-configuration).
Despite this, the job fails, because it takes a long time to execute, so my data is not updated.
What i can do process my jobs by batch successfully?
This is my kernel.php
<?php
namespace App\Console;
use App\Jobs\Seed\ApiPlayerStatisticJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new ApiPlayerStatisticJob)->everyFiveMinutes();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
My ApiPlayerStatisticJob.php
<?php
namespace App\Jobs\Seed;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class ApiPlayerStatisticJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
// echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
// echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
// echo PHP_EOL.'> PLAYER UPDATED ';
} else {
// echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
// echo PHP_EOL;
// echo PHP_EOL;
}
}
}
And my Seeder what i used for construct my job (by replication, excluding the print expressions):
<?php
use Illuminate\Database\Seeder;
use App\ApiExternal;
use App\ApiPlayer;
use App\ApiTeam;
class ApiPlayerStatisticsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$api_teams = ApiTeam::get();
foreach ($api_teams as $api_team) {
echo 'TEAM: '.$api_team->id;
$api_external_players = ApiExternal::getTeamPlayerStatistics($api_team->id);
foreach ($api_external_players as $api_external_player) {
echo PHP_EOL.'PLAYER: '.$api_external_player['id'];
$api_player = ApiPlayer::find($api_external_player['id']);
if ($api_player != null) {
$api_player->update($api_external_player);
echo PHP_EOL.'> PLAYER UPDATED ';
} else {
echo PHP_EOL.'X PLAYER DIDNT UPDATED ';
}
}
echo PHP_EOL;
echo PHP_EOL;
}
}
}
Finally, the static function ApiExternal::getTeamPlayerStatistics(int id)
do all requests necessaries to get th data (like 30 requests), so what i can do to process this job (or the seeder directly) in background without it fails?