SyncSubmitTask.php 3.7 KB
<?php

namespace App\Console\Commands\Sync;


use App\Exceptions\InquiryFilterException;
use App\Models\Project\Project;
use App\Models\SyncSubmitTask\SyncSubmitTask as SyncSubmitTaskModel;
use App\Services\SyncSubmitTaskService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;

/**
 *
 * Class SyncSubmitTask
 * @package App\Console\Commands
 * @author zbj
 * @date 2023/11/28
 */
class SyncSubmitTask extends Command
{

    protected $signature = 'sync_submit_task';
    protected $description = '询盘、访问异步任务';

    public function handle()
    {
        $backup = false;
        while (true) {
            $task_id = $this->getTaskId();
            if ($task_id > 2000000) {
                $backup = true;
            }
            if (empty($task_id)) {
                if ($backup) {
                    $this->backup();
                    $backup = false;
                }
                sleep(5);
                continue;
            }
            $this->output('任务' . $task_id . '开始');
            $task_info = SyncSubmitTaskModel::find($task_id);
            if (empty($task_info) || $task_info->status) {
                $this->output('任务不存在或者已执行');
                continue;
            }
            try {
                $project = Project::getProjectByDomain($task_info['data']['domain'] ?? '');
                $task_info->project_id = $project->id;

                SyncSubmitTaskService::handler($task_info);
                $task_info->status = 1;
                $task_info->save();

                $this->output('任务完成');
            } catch (InquiryFilterException $e) {
                $task_info->status = 1;
                $task_info->is_filtered = 1;
                $task_info->remark = $e->getMessage();
                $task_info->save();

                $this->output('任务完成');
            } catch (\Exception $e) {
                $task_info->retry = $task_info->retry + 1;
                if ($task_info->retry >= 3) {
                    $task_info->status = 2;
                    $task_info->remark = Str::substr($e->getMessage(), 0, 200);
                } else {
                    Redis::lpush('sync_submit_task', $task_id);
                }
                $task_info->save();

                $this->output('任务失败:' . $e->getMessage());
            }
        }
    }

    public function getTaskId()
    {
        $task_id = Redis::rpop('sync_submit_task');
        if (empty($task_id)) {
            $ids = SyncSubmitTaskModel::where('status', 0)->limit(100)->pluck('id');
            foreach ($ids as $id) {
                Redis::lpush('sync_submit_task', $id);
            }
            $task_id = Redis::rpop('sync_submit_task');
        }
        return $task_id;
    }

    /**
     * 输出处理日志
     */
    public function output($message): bool
    {
        echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
        return true;
    }

    /**
     * 备份数据
     * @author zbj
     * @date 2024/1/23
     */
    public function backup()
    {
        DB::beginTransaction();
        try {
            $table = (new SyncSubmitTaskModel())->getTable();
            $new_table = $table . '_backup_' . date('Ymd');

            //重命名当前表
            Schema::rename($table, $new_table);
            //克隆表数据
            DB::statement('CREATE TABLE ' . $table . ' LIKE ' . $new_table);

            DB::commit();

            $this->output('数据备份成功');
        } catch (\Exception $e) {
            $this->output('数据备份失败' . $e->getMessage());
            DB::rollBack();
        }
        return true;
    }
}