Coder Social home page Coder Social logo

jean-pasqualini / import Goto Github PK

View Code? Open in Web Editor NEW
5.0 2.0 1.0 336 KB

Tools for runner step specializer in etl (stable version: 0.4), (dev version: 1.1)

License: GNU General Public License v3.0

PHP 99.60% Makefile 0.40%
etl import symfony framework

import's Introduction

ImportBundle

Qualité

Scrutinizer Code Quality

Code Coverage

Build Status

Contribution

Lancer les tests
make test-unit
Analyser le coding style
make test-cs
Comment contribuer ?

Comment contribuer ?

Prérequis
  • Symfony >= 3.4.0, < 4.0.0
  • PHP >= 7.0.0

Installation

Etape 1: Télécharger le bundle

Ouvirr le terminal, entrer dans le répertoire du projet et éxécuter ces commandes pour télécharger la dernière version stable de ce bundle:

$ composer require darkilliant/import

Cette comamnde requis d'avoir le composer d'installer globalement, ceci est expliquer dans le chapitre d'installation de la documentation du composer.

Etape 2: Activer le Bundle

Puis, activer le bundle en l'ajoutant dans la liste du fichier app/AppKernel.php

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new Darkilliant\ProcessBundle\DarkilliantProcessBundle(),
            new Darkilliant\ImportBundle\DarkilliantImportBundle(),
            new Darkilliant\MqProcessBundle\DarkilliantMqProcessBundle(), // Ony when use message queueing for scale
        );

        // ...
    }

    // ...
}
Releasing
  • Version semver (majeure.mineur.bugfix)
  • De nouvelles fonctionalitées tous les 3 mois (0.1, 0.2, 0.3, 0.4, 1.1, 1.2, 1.3, ...)
  • Une version majeure tous les ans (même quand il n'y à pas changement majeur mais permettant de supprimer le BC)
  • Nous assurons la compatibilité descendante
  • Pas plus de deux version en cours maintenu pour les fix (version stable et version en cours de dev)
BC Break

Considèrer comme du cassage de compatiblité,

  • Changement de signature de méthode public, sauf si mis en @internal au niveau de la méthode ou de la classe
  • Suppression de méthode public, sauf si mis en @internal au niveau de la méthode ou de la classe
  • Suppression de propriété public
  • Suppression d'option dans un transformer ou une step
  • Ajout d'option sans default dans un transformer ou une step
  • Changement du comportement d'un transformer ou d'une step avec une même configuration

Qu'est-ce qu'on protège globalement par le contrat de retro-compatiblité ?

  • Le comportements des step, transformer ne doit pas changé avec une même configuration
  • Le fonctionnement du StepRunner avec une même configuration
  • Les méthodes publlques du ProcessState
  • Les méthodes publiques des steps et du step runner

Roadmap

Version Date de publication Date de fin de maintenance BC ?
0.2 Juin 2018 Juillet 2018 NON
0.3 Juillet 2018 Octobre 2018 NON
0.4 Octobre 2018 Janvier 2019 NON
1.1 Janvier 2019 Avril 2019 OUI
1.2 Avril 2019 Juillet 2019 NON
1.3 Juillet 2019 Octobre 2019 NON
1.4 Octobre 2019 Janvier 2020 NON
2.1 Janvier 2020 Avril 2020 OUI

Usage

Règles,

  • Vous utilisez donc vous contribuer à la documentation et aux bugfix. raller c'est bien mais agir c'est mieu.
  • Toujours travailler sur une version stable, une version en cours de développement n'est pas conseillé.

Cookbook,

import's People

Contributors

eyaraws avatar jean-pasqualini avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

eyaraws

import's Issues

Bug à l'instal

Cocur slugify à mettre dans les dépencances
Monolog à autoriser à partir de la version 2.12.1

Cannot autowire slugify
Cannot autowire "Symfony\Component\PropertyAccess\PropertyAccessor"
Vérifier l'existance de l'extension pcntl
Attention avec les logger qui sont en private

Release 0.3 (Juillet 2018)

Release note (ce qui ne sera pas fait pour cette release sera reporté à la prochaine),

  • Je veux pouvoir importer des lots conséquent avec des processus concurenciel (#1)
  • Je veux pouvoir utilser le dry-run pour valider mes données sans les persister (#5)
  • Je veux pouvoir supprimer des doublons dans le pipe (#8)
  • Je veux pouvoir valider un objet php via le validateur de symfony (#9)
  • Je veux pouvoir filtrer des données dans le pipe (#11)
  • Je veux faciliter la configuration du mapping et de la transformation des données en dissociant les deux étapes dont la configuration est difficile aujourdh'ui) (#12)
  • La barre de progresssion pour le parcours d'un csv ne marche pas correctement (une branche est présente pour sa) (#15)
  • L'isolation de processus s'éxécute de manière séquenciel et non simultané comme sa devrais être le cas (une branche de travail est sur sa) (#16)
  • Je veux une gestion intelligente des deprecated pour les steps (#13)
  • Je ne veux pas marquer pour persistance les objet juste avant le flush mais pendant l'itération (#17)
  • Je veux pouvoir désactiver une micro-tache en mode prod (#18)
  • Je veux avoir la possibilité d'utiliser un index local en mémoire afin d'éviter des select (#19)
  • Je veux pouvoir itérer sur un xml en récupérant seulement un type de noeud (#22)
  • Je veux pouvoir faire du profilling sur mon traitement pour identifier les goulots d'étranglement à optimiser (#20)
  • Documenter l'utilisation de la progressbar et la nouvelle option globale enabled (#24)

Release 0.4 (Octobre 2018)

Release notes,

  • Je veux pouvoir boucler sur mon traitement avec une limite de temps/itération (#26)
  • Je veux pouvoir éxécuter mon script en fonction d'un event du filesystem sur un fichier ou un dossier (inotifywait) (#28)
  • Je veux trouver des fichiers et les iterer dans le pipe (#29)
  • Je veux m'assurer que les events système soit bien broadcaster dans les enfants (#30)
  • Permettre de passer par rabbitmq pour gérer de très gros import avec une grande scalabilité (#35)
  • Je veux faire remonter au process notifier si une itération de boucle à réussie son traitement ou non via de nouvelle méthode onSucessLoop(ProcessState $state) et onFailedLoop(ProcessState $state) (#36)
  • Je veux pouvoir construire moi même les paramètre qui vont servir à résoudre une entité dans certain cas particulier. (#38)
  • [BUG] Passer le whitelist au doctrine persister step (#39)
  • Passer au processState le nom du process courant (#40)
  • Je veux un contexte de boucle ainsi qu'un accès plus simple aux options/context (#42)
  • Je veux pouvoir exclure des logs certaines données présente dans le context (#42)
  • [BUG] il faut s'assurer que le verbose est pris en compte dans le process enfant et bien sur dynamiser l'environement en fonction de l'environement du parent ainsi que le context
  • Je veux qu'une exception puisse être généré quand mon flux rencontre des données en doublon (#44)
  • Je veux pouvoir configurer le sonar de la progress bar (#45)
  • Il faut pouvoir choisir ou non de skiper la première ligne l'ors de la lecutre d'un csv (#46)
  • La résolution dynamique des options au niveau du finalize pose problème quand les donnée ne sont plus dans le pipe (#47)

[OPTIMISATION] Trouver les goulots d'étranglement

Goulots

  • Le goulot d'étranglement du moteur de requête doctrine permet juste de passer de 1 minute à 23 seconde et est donc exclu (PAS FORCEMENT VU LA CONCLUSION)
  • Le goulot d'étranglement du manque d'index sur l'ean (ajout d'un index pour solution) (passage de 400/s dégréssif à 1000/s)
  • Le goulot d'étranglement qui vérifie si le produit existe permet de passer à 2500/s et semble donc d'intêret à analyser (usage d'un index local en mémoire plus rapide qu'un appel à la bdd à solutionner ce point) (empreinte mémoire plus importante en contrepartie à voir du coté d'un cache clé/valeur (redis/memcache) qui permettera également de partager ce cache pour une meuilleur scalabilité)
  • Le goulot d'étranglement du serializer réduit le flow de 7200/s à 2500/s mais sera lui même limite par la performance du flush
  • Le goulot d'étranglement du flush réduit à 2500 par seconde (qu'on ai un batch de 5000 ou de 50000) (la piste de l'insert étendu n'est pas si écarté que sa)
  • Le goulot d'étranglement du process unique résolu par process isolé ou message queue ne semble pas être intéréssent car il est limité par les autres goulots d'étranglements.

Constat

On constate que c'est bien le couple du flush et de la désérialization qui divise les performance par 3.
Ainsi on met 1mn (2500/s) là on pour rais mettre 20 secondes (7200/s) pour 150 000 élements.

  • Sans utiliser de sérializer et avec un système d'insert étendu on est à 7200/s
  • L'usage du serailizer limite à 2500/s
  • L'usage du flush avec insert classique limite à 2500/s
Piste
  • Il faut monitorer par step le temps de traitement par itération et le temps d'attente pour calculer le potentiel de traitement suplémentaire
  • J'ai l'impression que ces goulots d'étranglement empêche la scalabilité
    - si je met une queue pour un goulot d'étranglement sa reste bloquer sur l'autre
    - peut être une queue pour les deux queue pour différer les deux goulots à savoir une pour la serialization et une pour le flush
  • Sinon l'usage d'insertion étendu avec du switch table pourrais être ne idée très intéréssente
  • Il serait intêresent de pouvoir identifier ces goulot d'étranglement de manière bien plus intéréssente avec un système de stat où l'ont vois le nombre d'ack par seconde. (statsd ?) (il serait cool aussi en mode débug de pouvoir désactiver un noued pour constater en réel les effets)
  • Pour les cas spéciaux peut être permettre de faire un INSERT/UPDATE DQL avec le mapping des entitié car doctrine ne permet pas de faire d'insert en DQL donc à creuser)
  • Peut être faire un test sans sérialization avec un paralélisme uniquement sur le flush pour voir

[WIP] Release 1.1 (Janvier 2019)

🔴 Pour la future release

  • Supprimer les deprecated
  • Changer la terminoligie de Step par MicroTask afin que tout le monde comprenne qu'il ne s'agit pas de workflow mais de tache indépendante.
  • Ajouter la possibilité via le option value resolver, d'utiliser des transformer qui seront eux déplacer dans le ProcessBundle
  • Je veux pouvoir automatiquement résoudre le where quand il y a des relation qui ne sont donc pas baser sur des ids.
  • Je veux pouvoir exposer une micro-tâche sous forme d'une cloud function dont les appels sont dans un message queue avec des meta-data de routage vers la prochaine cloud function à appeler
  • Je veux pouvoir trier mon pipe pour prioriser certaines élements afin qu'il soit traiter en premier
  • Je veux pouvoir obtenir un fichier qui ne contient que les lignes ajouté/modifié entre un ancien fichier et un nouveau fichier (à voir si on gère sa avec un simple diff ou un système de parcours intelligent)
  • Il faut des diagrammes de flux et de la documentation sur le workflow

[CLEAN BC] Release 1.1 (Janvier 2019)

  • La transformation d'un tableau en objet est désormait assuré par le serializer de symfony, l'implémentation alternative sans usage du deserializer pourra être enlever si on ne constate pas de besoin de ce coté
    • Darkilliant\ImportBundle\Step\LoadObjectStep
    • Darkilliant\ImportBundle\Step\ArrayTargetResolverStep
    • Darkilliant\ImportBundle\TargetResolver\ArrayTargetResolver
    • Darkilliant\ImportBundle\TargetResolver\DoctrineTargetResolver
    • Darkilliant\ImportBundle\Loader\ObjectLoader
    • Darkilliant\ImportBundle\Loader\AbstractLoader
    • Darkilliant\ImportBundle\Loader\LoaderInterface
  • La classe NullDoctrinePersister n'est pas utilisé ni dans les tests ni pour le dry-run, il faudra donc l'enlever

Retour bug

  • Il faut permettre une sortie avec un état fail par example avec le status RESULT_EXIT.
  • Il serait intéressent de pouvoir throw ou non une erreur à la place du warning quand une ligne est dupliqué (potentiellement via une option de configuration throw_error) (execption NonUniqueException)
  • il serait intéressent de pouvoir faire rendre l'unicité sur du ou. (low)
  • il faudrait pouvoi, r configurer le maxMemory et minItem de la progressBar par step via les options de configuration
  • il y a un bug sur l'isolate process step qui passe les clé du context avant un espace devant.
  • il faut s'assurer que le verbose est pris en compte dans le process enfant et bien sur dynamiser l'environement en fonction de l'environement du parent
  • Je veux pouvoir appliquer des transformation sur le context en plus des data
  • il serait intéressent d'avoir un hasOption et un getOption($key, $defaultValue)
  • il serait intéressent d'avoir un hasContext et un getContext($key, $defaultValue)
  • Il faut retravailler la gestion du cache car on ne cherche pas toujours par toute les clé en permettant dans la configuration du cache de dire sur quels combinaisons de clé on souhaite indexé
  • Il faut pouvoir choisir ou non de skiper la première ligne l'ors de la lecutre d'un csv
  • Il ne faut pas résoudre dynamiquement les options dans le finalize sinon on tente de récéprer des données qui ne sont plus dans le pipe

Screen de tests

Import d'un xml de 2.7 Gb avec 472 000 produits

  • Pas de persistance
  • Pas de parralélisme
  • Debug
  • Mapping
darkilliant_process:
    process:
        import_product_xml:
            logger: monolog.logger.import_product
            steps:
                -
                    service: 'Darkilliant\ImportBundle\Step\XmlExtractorStep'
                    options:
                        filepath: '@[context][filepath]'
                        node_name: 'Sku'
                        progress_bar: true
                -
                    service: 'Darkilliant\ProcessBundle\Step\MappingStep'
                    options:
                        mapping:
                            'entity'               : 1
                            'label'                : '@[data][title]'
                            'external_id'          : '@[data][sku]'
                            'ref'                  : '@[data][sku]'
                            'pj_primary_family_id' : '@[data][primaryfamilyId]'
                            'pj_furniture'         : '@[data][furniture]'
                            'description'          : '@[data][description]'
                            'pj_description_full'  : '@[data][descriptionFull]'
                            'pj_description_long'  : '@[data][descriptionLong]'
                            'pj_dimensions'        : '@[data][dimensions]'
                            'pj_width'             : '@[data][width]'
                            'pj_diameter'          : '@[data][diameter]'
                            'pj_height'            : '@[data][height]'
                            'pj_depth'             : '@[data][depth]'
                            'pj_large_image'       : '@[data][largeImage]'
                            'pj_medium_image'      : '@[data][mediumImage]'
                            'pj_small_image'       : '@[data][smallImage]'
                            'pj_silhouette_image'  : '@[data][silhouetteImage]'
                            'external_ref'         : '@[data][primaryCategoryId]'
                -
                    service: 'Darkilliant\ProcessBundle\Step\DebugStep'
                    enabled: false
                    options: []

Résultat,
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.