Как отправить данные из планировщика в команду ремесленника в Laravel 5.5 - PullRequest
1 голос
/ 10 марта 2020

Хорошо, поэтому мне в основном нужно сгенерировать файл json, используя планировщик Laravel и пользовательскую команду ремесленника (указанный список на самом деле является списком популярных городов в нашем приложении). Так что я пошел вперед и сделал именно это. Вот определение моей команды Artisan:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Services\PlaceService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;

class CitySearch extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'city:search {--locale=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generates the list of the most popular cities to be used across the application when we need it.';

    private $placesService;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(PlaceService $placesService)
    {
        $this->placesService = $placesService;
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        App::setLocale( $this->option('locale') );


        $request = Request::create(route('api.search-places'), 'GET', ['maxResults' => 3000, 'isArtisan' => true]);

        $request->headers->set('Accept', 'application/json');
        $request->headers->set('Api-Key', 'aaaaaaaaaaaa');
        // $request->headers->set('Api-Key', '43JSOSH333KSOH555WHO99');
        $request->headers->set('App-client', 'web');

        $response = app()->handle($request);
        $content = json_decode($response->getContent());

        $results = array_map(function($element){

            if($element->type == "City")
                $context = ['an', 'se', 'me'];
            else
                $context = ['se'];



            return ['displayName' => $element->displayName, 'context' => $context];
        }, $content->data);

        print(json_encode($results));



    }
}

Затем я вошел в планировщик и добавил следующее, чтобы команда запускалась раз в неделю:

namespace App\Console;

use App\Console\Commands\Admin\RedFalcon\PendingTransactionNotificator;
use App\Console\Commands\Admin\RedFalcon\FraudTransactionNotificator;
use App\Console\Commands\CardGenerate;
use App\Console\Commands\Communauto\Stats;
use App\Console\Commands\CPS\Archiver;
use App\Console\Commands\CPS\AutoCasher;
use App\Console\Commands\CPS\Autofixer;
use App\Console\Commands\CPS\Beta\Testers;
use App\Console\Commands\CPS\BNC\EmailFailedBankTransaction;
use App\Console\Commands\CPS\BNC\FeedComposer;
use App\Console\Commands\CPS\BNC\Feeder;
use App\Console\Commands\CPS\BNC\FeedMediator;
use App\Console\Commands\CPS\BNC\FeedReporter;
use App\Console\Commands\CPS\BNC\Parametrizer;
use App\Console\Commands\CPS\Captor;
use App\Console\Commands\CPS\ConfirmationFix;
use App\Console\Commands\CPS\ConfirmationCodeRemoval;
use App\Console\Commands\CPS\DB\RideArchiver;
use App\Console\Commands\CPS\DB\RideFixer;
use App\Console\Commands\CPS\Rider;
use App\Console\Commands\CPS\Test\Resetter;
use App\Console\Commands\CPS\Transactor;
use App\Console\Commands\CPS\Troubleshooting\Experiment1;
use App\Console\Commands\Notifications\ApnFeedbackService;
use App\Console\Commands\RelavelTester;
use App\Console\Commands\UpdateCityPopularity;
use App\Console\Commands\Util\FixBankTransactionTable;
use App\Console\Commands\Util\FixPreauthorizationTable;
use App\Console\Commands\Util\ResetPassword;
use App\Console\Commands\CitySearch;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;

class Kernel extends ConsoleKernel
{

    protected $list;
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        CardGenerate::class,
        Rider::class,
        Autofixer::class,
        Captor::class,
        Transactor::class,
        Archiver::class,
        FeedComposer::class,
        FeedMediator::class,
        Feeder::class,
        Parametrizer::class,
        RideFixer::class,
        RideArchiver::class,
        RelavelTester::class,
        FixPreauthorizationTable::class,
        PendingTransactionNotificator::class,
        FraudTransactionNotificator::class,
        FixBankTransactionTable::class,
        Resetter::class,
        Testers::class,
        Stats::class,
        Experiment1::class,
        FeedReporter::class,
        ResetPassword::class,
        AutoCasher::class,
        ConfirmationFix::class,
        ConfirmationCodeRemoval::class,
        CitySearch::class,
        UpdateCityPopularity::class,
        EmailFailedBankTransaction::class,
        ApnFeedbackService::class
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('city:search --locale=fr')
            ->mondays()
            ->at('14:40')
            ->sendOutputTo(storage_path() . "/app/city-fr.json");

        $schedule->command('city:search --locale=en')
            ->mondays()
            ->at('14:40')
            ->sendOutputTo(storage_path() . "/app/city-en.json");
    }

    /**
     * Register the Closure based commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        require base_path('routes/console.php');
    }
}

Теперь это работает относительно хорошо ... кроме иногда это терпит крах. Когда это происходит, два файла json заполняются сообщениями об ошибках вместо фактических данных. Что я хотел бы сделать, это в основном сохранить исходный список перед выполнением команды, и в случае сбоя чего-либо я хотел бы вывести этот список в файл и записать ошибку. Прямо сейчас, все идет в файл и, конечно, я получаю кучу ошибок в моем приложении, потому что список городов недействителен.

Так как я нахожусь в Laravel 5.5, я попытался использовать "до" и «после» хуков (onFailure и onSuccess недоступны в моей версии фреймворка) и придумали это:

$schedule->command('city:search --locale=fr')
->everyMinute()
->before( function(){ 
    $this->list = json_decode(file_get_contents(storage_path() . "/app/city-fr.json"));
})
->after(function(){
    $test = json_decode(file_get_contents(storage_path() . "/app/city-fr.json"));
    Log::debug($test);
})
->sendOutputTo(storage_path() . "/app/city-fr.json");

Итак, пока я могу успешно получить исходный список из файла до начала процесса в хуке «после» файл все еще пуст, поэтому у меня нет возможности узнать, произошел ли сбой процесса или нет.

Кто-нибудь знает, как я должен go об этом? Такое ощущение, что решение прямо перед моим лицом, но я просто скучаю по нему.

1 Ответ

0 голосов
/ 11 марта 2020

Ладно, это момент для меня. Оказывается в ловушке 'after', у меня был доступ к файлу, но причина, по которой мой вывод был пустым, заключалась в том, что метод json_decode возвратил false, потому что содержимое файла было недопустимым json (что и было Я пытался проверить с самого начала). Во всяком случае, как только я закончил собирать кусочки моего рассеянного мозга, следующее оказалось отлично работает:

$schedule->command('city:search --locale=fr')
            ->everyMinute()
            ->before( function(){ 
                $this->list = file_get_contents(storage_path() . "/app/city-fr.json");
            })
            ->after(function(){
                if(!json_decode(file_get_contents(storage_path() . "/app/city-fr.json")))
                {
                    $fp = fopen(storage_path() . "/app/city-fr.json", 'w');
                    fwrite($fp, $this->list);
                    fclose($fp);
                }
            })
            ->sendOutputTo(storage_path() . "/app/city-fr.json");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...