Консоль Symfony для cron или расписаний задач в сочетании с исполнителем задач - PullRequest
0 голосов
/ 31 мая 2018

Для моего проекта мне нужно импортировать 12-15 файлов, варьирующихся от CSV, xml до gz.Поскольку все файлы имеют свои собственные структуры, и мне пришлось создать 1 команду для каждого файла.Но это слишком много, и я хочу создать общий импорт для всех файлов.

Требования:

  • Сценарий импорта должен запускаться каждый час
  • Сценарий импорта должен импортировать категорию + товары из импорта
  • Сценарий импорта должен проверить, соответствует ли моя категория категории импорта, если да, он должен добавить информацию в базу данных, если не игнорировать.
  • Импорт не должен влиять на веб-сайт, если онимпортирует в фоновом режиме.

Что у меня есть на данный момент в моей команде:

$handle = fopen("https://example.csv",'r');

$output->writeln('Downloading done!');

$categortArray = [];
$categortA = [];
while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{
    $categortA [ $row[21]] = $row[23] ;
    $categortArray [] = $row[21];
}

$output->writeln('Updating category list !');
$result = array_unique($categortArray);
$result2 = array_unique($categortA);

$distributor = $distributor->findByName("Name of Distributor");

foreach ($result as $productgroup) {
    $result = $categoryRepository->findByTitle($productgroup);
    if (empty($result)){
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setDescription("Category Description");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

foreach ($result2 as $key => $productgroup) {
    $result = $categoryRepository->findByTitle($key);

    /** @var $result Category */
    if ($result !== null) {
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setParent($result[0]);
        $category->setDescription("Name of Distributor");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{

    foreach ($child as $c) {
        if ($c->getTitle() === $row['21']) {
            $product = new Product();
            $product->setName($row[1]);
            $product->setCategory($categoryTop);
            $product->setSku($row[14]);
            $product->setEanUpc($categoryTop->getId());
            $this->productService->save($product);
        }
    }
}

Опции, которые я могу придумать:

  • Извлеките все сценарии автоматического импорта в 1 команду и запускайте ее каждый час.Этот вариант не сложный, но я не думаю, что это лучшее решение, так как оно потребует большого количества ресурсов на моем сервере.
  • Создайте планировщик задач в сочетании с исполнителем задач, где мы регистрируем каждое событиеразличные шаги, такие как загрузка файла, чтение файла, проверка наличия, проверка соответствия категории, проверка наличия продукта, проверка наличия обновленного продукта и т. д. Для этого варианта я хочу создать свой собственный планировщик + бегунок, но у меня естьНе так уж много опыта и не знаю, поможет ли это моему проекту.Так как каждая задача будет поставлена ​​в очередь, это облегчает проверку, если что-то не получается

Консультирование для моей текущей команды Symfony также приветствуется.

1 Ответ

0 голосов
/ 31 мая 2018

В прошлом я решал нечто похожее, теперь эти советы зависят от того, сколько данных вам нужно синхронизировать (у меня было около 8 источников, каждый из которых около 10 000 элементов синхронизировался не позднее, чем через 15 минут).

Архитектурарешения выглядит следующим образом:

  • Для каждого источника у вас есть Tranformer, который загружает исходный файл и анализирует его в одном общем TransformedDTO, в вашем случае это может быть либо один Продукт, содержащий категорию, либо два преобразованных объекта.для 2 разных процессоров
  • Далее у вас есть процессор - этот получает TransformedDTO, теперь для оптимизации я вычислил контрольную сумму данных и сравнил ее с контрольной суммой последнего запуска на основе продукта.Сейчас занимаюсь обновлением только при необходимости.Если вы вставляете только продукты, этот шаг не требуется.
  • Здесь вы можете сделать, чтобы этот процессор просто проверял, изменился ли продукт, если это так, вы добавляете обновление в очередь и обрабатываете другой процессор.Но это только следующий возможный шаг.

Преимущества этого решения:

  • Добавление нового импорта состоит из простой записи одного Transformer
  • Вы можете иметь некоторое кэширование/ оптимизация логики в вашем процессоре (это обычно узкое место, так как для этого нужно выполнить довольно много операций), но поскольку он используется совместно, для этого есть место, и одна оптимизация влияет на все.

Для планирования, зависит от ваших потребностей - я бы придерживался возможности запускать разные расписания в разное время и проверять, с каким интервалом обновляются источники, и синхронизировать с вами время обновления.

Пример TransformedDTO.Это не что иное, как заполнитель для ваших данных, он работает как вход для процессоров и как выходной преобразователь.

class Product {
    public $sku;
    public $category;
    public $name;
    // Everything else which your processor know how to process
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...