Développer avec RBS Change : [Résolu] Problème traitement tache qui agit sur les clients

  • 81791.1

    11/11/2013 15:04


    mamous
    Rang : Expert
    Bonjour,

    J'ai créé une tâche qui agit sur les groupes des clients selon une condition d'un filtre, le problème c'est qu'avec un grand nombre de client la tache se bloque sur un client sans qu'elle ne s'arrive à une fin (d'après les test le traitement ne prend que presque 7000 clients et pas plus) donc je devrais relancer la tache pour que je puisse aboutir à une fin....
    Y'a t -il une manière à ce que je peux remédier à ce problème???
    Dans le log de l'application il m’écrit rien déjà

    Cordialement

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.2 en réponse à 81791.1 écrit par mamous

    11/11/2013 17:20


    mamous
    Rang : Expert
    Re,

    J'ai ajouter un array_chunk du customers mais en vain la tache se bloque toujours dans les environs des 7000 ème customer!!!!

    J'ai essayer même d'enlever toutes les conditions que j'ai dans la tache, je fais de sorte à initialiser tout les clients à un groupe tarifaire X.
    Voici le bout de code de l'initialisation :
    $customers=customer_CustomerService::getInstance()->createQuery()->find();
        	
        	foreach (array_chunk($customers, 500) as $customerArray)
    		{
    			Framework::warn('---------------- NEW CHUNK ---------------------');
    			
    			foreach($customerArray as $customer)
    			{
    				Framework::warn('---------------- Client ---------------------'.$customer->getEmail());
    					$customer->setTarifgroup($groupInit);
    					$customer->save();
    			}
    			
    		}

    Il m'affiche tout les clients séquentiellement mais se coince sur un dernier, et ce coincement est aléatoire càd lorsque je relance par exp la tache, c'est pas evident que sa serait le même client en cause !!!


    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.3 en réponse à 81791.2 écrit par mamous

    13/11/2013 10:25


    Jean-Michel
    Titre : Community Manager
    Rang : Expert
    Bonjour mamous,

    Avez-vous découpé votre tâche de sorte à ce qu'elle s'exécute en chunk et fait varier la taille des lots?

    Pour voir une tâche planifiée utilisant des chunks, je vous invite à regarder le fonctionnement de la tâche de compilation des produits ou d'indexation des documents.

    Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
    Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié.
  • 81791.4 en réponse à 81791.3 écrit par Jean-Michel

    13/11/2013 10:34


    mamous
    Rang : Expert
    Bonjour Jean Michel,
    Effectivement, j'ai changer la tache à ce qu'elle s'execute en chunk comme dans le code que je vous ai fourni, sa a améliorer un peu le traitement, j’atteins maintenant les 9000 clients mais j'ai toujours le blocage.
    Sinon, je suis entrain deja de tester en utilisant des batchs d'ajout et suppression comme dans le cas de la tache de Rafraichissement de groupe d'utilisateurs mais bon je sais pas si le fait d'employer le
    f_util_System::execHTTPScript
    pourra résoudre ce problème ???
    Je vous tiendrais au courant des avancements.
    Merci

    Cordialement à vous

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • Message supprimé par son auteur.
  • 81791.6 en réponse à 81791.4 écrit par mamous

    13/11/2013 11:19


    Jean-Michel
    Titre : Community Manager
    Rang : Expert
    Bonjour,

    Le code que vous avez fournit ne correspond pas à l'utilisation de chunk tel qu'il est mis en oeuvre dans les tâches que je vous ai cité.

    Ce qui vous arrive probablement et que j'imagine facilement, c'est soit un timeout soit un memory limit.

    Or l'utilisation le découpage du traitement en lot (chunk) va effectivement résoudre ce type de problème.
    Il est des sites en production ayant des volumes beaucoup plus important que 9000 documents (que ce soit au niveau de la base client ou du catalogue produit, ou encore des pages) et arrivant à s'exécuter sans aucun problème avec cette mécanique.

    Pour expliquer comment ca fonctionne ; dans le script appelant on fait une requête minimale, de sorte à ce que l'emprunte mémoire soit la plus faible possible et le temps d'exécution soit le plus petit possible. Ce script invoque ensuite son chunk par "f_util_System::execHTTPScript".
    C'est dans le chunk que l'on va exécuter le code lourd et couteux en temps d'exécution et emprunte mémoire.
    Pendant que le chunk s'exécute il n'y a pas de décompte de temps qui est fait pour l'appelant ni de consommation mémoire supplémentaire, c'est sur le chunk que ces décomptes sont fait et c'est ce qui permet effectivement de fait un traitement de masse effectif. C'est pour cela qu'il est très important que le script appelant soit le plus minimal/optimisé possible.

    Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
    Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié.
  • 81791.7 en réponse à 81791.4 écrit par mamous

    13/11/2013 11:21


    mamous
    Rang : Expert
    Re,
    Voici le code que j'ai utilisé pour le traitement des clients :
    		$customers=customer_CustomerService::getInstance()->createQuery()->find();
    		$tm = f_persistentdocument_TransactionManager::getInstance();
    		try
    		{
    			$i=0;
    			
    				foreach (array_chunk($customers, 500) as $customerArray)
    				{
    					Framework::warn('---------------- Chunk -----------------'.$i);
    					$i=$i+500;
    					$this->plannedTask->ping();
    					$result = f_util_System::execHTTPScript($batchPath, $customerArray);
    					Framework::warn('---------------- Resultat -----------------'.$result);
    				}
    			
    		}
    		catch (Exception $e)
    		{
    			$tm->rollBack($e);
    		}
    Dans les logs j'ai le résultat suivant
    2013-11-13 10:17:29	[WARN]	---------------- Début DynamictarifgroupTask -----------------
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------0
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------1000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------1500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------2000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------2500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------3000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------3500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------4000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------4500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------5000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------5500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------6000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------6500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------7000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------7500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------8000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------8500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------9000
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------9500
    2013-11-13 10:17:39	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:39	[WARN]	---------------- Chunk -----------------10000
    2013-11-13 10:17:40	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:40	[WARN]	---------------- Chunk -----------------10500
    2013-11-13 10:17:40	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:40	[WARN]	---------------- Chunk -----------------11000
    2013-11-13 10:17:40	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:40	[WARN]	---------------- Chunk -----------------11500
    2013-11-13 10:17:40	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:40	[WARN]	---------------- Chunk -----------------12000
    2013-11-13 10:17:40	[WARN]	---------------- Resultat -----------------Invalid signature
    2013-11-13 10:17:40	[WARN]	---------------- Fin DynamictarifgroupTask -----------------
    

    Je sais pas pourquoi le execHTTPScript me retourne un Invalid signature malgré que j'ai utilisé de même que dans la compilation de produits!!

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.8 en réponse à 81791.7 écrit par mamous

    13/11/2013 14:23


    mamous
    Rang : Expert
    Dois je mettre un array de Integer en second paramètre dans la méthode f_util_System::execHTTPScript ou peut importe parce que là je trouve pas l'explication de l'affichage de Invalid Signature dans les logs de l'application???

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.9 en réponse à 81791.8 écrit par mamous

    14/11/2013 09:33


    mamous
    Rang : Expert
    Bonjour,

    Maintenant c'est bon la tâche tourne parfaitement lorsque j'ai passé des Ids dans le second paramètre de la méthode execHTTPScript, le problème maintenant c'est que la condition n'est pas satisfaite à 100% par exp si je choisit le filtre sur les clients qui appartiennent à mon site (à raison d'avoir tout les clients en résultat) de 20013 clients j'en ai que 19987 clients les autres ne sont pas passé à ce groupe là de même suite à ce test j'ai voulu rendre tout les clients à l'état initiale j'ai relancé la tache sans choisir de filtre (à raison d'avoir tout les clients dans le groupe initiale) j'en ai que 20008 clients...
    Dans les logs y'a rien et sinon j'ai choisi un chunk de 500 utilisateurs, j'ai essayé de le diminuer même à 10 et j'ai toujours le même résultat...
    Autre indication, c'est que les clients ne sont pas ordonnées càd que c'est pas les derniers clients qui n'ont pas étaient traiter mais des clients aléatoires comme si la tâche les a perdu lors de passage du chunk au batch de traitement!!!
    Cordialement à vous

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.10 en réponse à 81791.9 écrit par mamous

    14/11/2013 12:07


    Jean-Michel
    Titre : Community Manager
    Rang : Expert
    Bonjour,

    Votre boucle initiale (celle qui appelle le chunk) n'est pas optimale ; moins il y aura de traitement dedans, mieux ce sera, il faut donc comprendre que la requête pourrait également être décalée dans le chunk ; ce qui sera donc également plus pérenne, puisque l'on déporte la consommation mémoire dans un autre script.
    Dans la dernière version de votre script vous faisiez un instanciation des documents directement dans la requête, ce qui a effectivement un impact direct sur la consommation mémoire ; en bref votre première version n'avait aucune différence dans les faits avec la première. Il faut donc ne récupérer que les ids de documents.

    Par ailleurs, si votre filtre ne comporte pas d'indication de tri, alors oui effectivement la requête ne sera pas triée, il en est de même en langage SQL, et l'ordre ne peut être garantit.

    D'autre part si votre condition n'est pas satisfaite à 100%, dans ce cas il est fort probable que votre condition soit incomplète et/ou erronée. Que ce soit dans une requête SQL ou en programmation pure ; si une conditionnelle n'est pas correcte, le résultat ne peut pas être celui auquel on s'attend, et ce quel que soit le volume de donnée testé.
    A vous de débuger votre condition/filtre et de comprendre quel est l'origine du problème.

    Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
    Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié.
  • 81791.11 en réponse à 81791.10 écrit par Jean-Michel

    14/11/2013 12:23


    mamous
    Rang : Expert
    Bonjour et merci pour votre réponse,

    C'est ce que je viens de faire déjà, après la condition du filtre, je fais un affichage du nombre de résultat que je dois avoir (un count($ids)) il m'affiche bien le nombre que je dois avoir, mais après lors du traitement j'ai pas effectivement ce nombre de clients.
    Sinon pour l'instanciation du document, si le fais pas eu corps de la tâche, ou dois je le faire alors??
    Parce que là ce que je dois faire en besoin de cette tache c'est de placer les clients satisfaisant à la condition sous le groupe tarifaire X et les clients non satisfaisant à la condition sous un autre groupe, du coup je me trouve obligé de traiter tout les clients!!!
    Pour améliorer un peut les choses j'ai changer dans le code de la tâche de manière à ce que je transmet au batch tout les clients et après le traitement du filtre se fait dans ce dernier je sais pas si ce que j'ai fais peut m'être utile pour l'optimisation des performances ou c'est pas le cas?


    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.12 en réponse à 81791.11 écrit par mamous

    14/11/2013 15:12


    Jean-Michel
    Titre : Community Manager
    Rang : Expert
    La solution consiste en :
    * au maximum récupérer les id satisfaisant la condtition dans le script de base
    * invoquer le chunk (= script invoqué par execHTTPScript) en un nombre d'id (500, 10...)
    * dans le chunk, instancier les documents correspondant aux ids
    * dans le chunk faire les modification sur les documents et les enregistrer.

    Si votre requête retourne X résultats, vous devez en traiter X, sinon vous avez un problème dans votre code. Si vous passez X ids au chunk, alors ce dernier doit en traiter X, il n'y a pas de disparition d'éléments qui puisse se produire.

    Etes-vous sûr de catcher toutes les exceptions, et de na pas avoir des exceptions qui se produise à un endroit et empêche ainsi l'exécution de votre code sur une partie du chunk?

    Pour une meilleure réponse, pensez à indiquer la version sur laquelle vous rencontrez des difficultés, ainsi que son type (CMS ou eCommerce core).
    Pour tout problème d'installation indiquez le nom de l'hébergeur et s'il s'agit d'un serveur mutualisé ou dédié.
  • 81791.13 en réponse à 81791.12 écrit par Jean-Michel

    14/11/2013 15:42


    mamous
    Rang : Expert
    Bonjour,

    J'ai déja modifier le script de la tâche de manière à séparer les traitement sur deux script différents (comme c'est fait dans la tache de rafraichissement des utilisateurs),maintenant pour les erreurs j'ai essayer le max de catcher toutes les exceptions qui pourront provenir soit du côté de la tâche en elle même soit coté des batchs.
    sinon pour le point d'invocation du chunk j'ai pas bien saisi qu'est ce que vous voulez me dire comment je pourrais l'invoquer en un nombre d'id ???

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.14 en réponse à 81791.11 écrit par mamous

    14/11/2013 16:50


    mamous
    Rang : Expert
    J'ai toujours le problème!!
    voilà je vous file les bouts de code en espérant que cela va vous être utile:
    <?php
    
    class moduleSpec_DynamictarifgroupTask extends task_SimpleSystemTask
    {
     Framework::warn('--------------- Début DynamictarifgroupTask ----------------');	
    $i=0;
    $group = $this->getInstanceByCodereference('VPTARIFGROUP');
    $groupInit = $this->getInstanceByCodereference('ALLCLIENT');
    $errors=array();
    //Récupérer la condition du filtre
    if ($group instanceof customer_persistentdocument_tarifcustomergroup)
    {
     $queryIntersection = f_persistentdocument_DocumentFilterService::getInstance()->getQueryIntersectionFromJson($group->getQuery());
    				$newIds = $queryIntersection->findIds();
    }	
    $oldIds=$this->getAllCustomerIds();
    if($newIds)
    {
    	$initCustomers = array_diff($oldIds, $newIds);
    	$VpCustomers = array_intersect($newIds, $oldIds);
    }
    else
    {
    	$initCustomers=$oldIds;
    	$VpCustomers = NULL;
    }
    $batchPath = $this->getRemoverBatchPath();
    if($initCustomers)
    {
    	foreach (array_chunk($initCustomers, 500) as $batch)
    	{
    		$this->plannedTask->ping();
    		$result = f_util_System::execHTTPScript($batchPath, $batch);
    		// Log fatal errors...
    		if ($result != 'OK')
    		{
    			$errors[] = $result;
    		}
    	}
    }
    $batchPath = $this->getAdderBatchPath();
    if($VpCustomers)
    {
    	foreach (array_chunk($VpCustomers, 500) as $batch)
    	{
    		$this->plannedTask->ping();
    		$result = f_util_System::execHTTPScript($batchPath,$batch);
    		// Log fatal errors...
    		if ($result != 'OK')
    		{
    			$errors[] = $result;
    		}
    	}
    }
    if (count($errors))
    {
    	Framework::warn(implode("\n", $errors));
    }...
    }

    Et voilà une partie du traitement du batch
    <?php
    $userIdArray = array_slice($_POST['argv'], 1);
    $i=0;
    $group = getInstanceByCodereference('VPTARIFGROUP');
    Framework::warn('---------- IN Adder ----------- ');
    $tm = f_persistentdocument_TransactionManager::getInstance();
    foreach ($userIdArray as $userId) 
    {
    	try 
    	{
    		Framework::warn("User -----$userId ----- num $i");
    		$tm->beginTransaction();
    		$user=customer_CustomerService::getInstance()->createQuery()
    					->add(Restrictions::eq('id', $userId))->findUnique();
    		$user->setTarifgroup($group);
    		$user->save();
    		$i++;
    		$tm->commit();
    	} 
    	catch (Exception $e)
    	{
    		Framework::warn($e);
    	}
    }
    ...

    Alors?
    J'ai toujours le problème de ne pas traiter tout les clients, même j'ai supprimer les clients qui étaient en cause, il a toujours laisser une vingtaine de clients sans les traiter et sans mettre en retour une trace dans les logs...

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.15 en réponse à 81791.14 écrit par mamous

    14/11/2013 18:04


    mamous
    Rang : Expert
    Re,
    Je crois qu'on s'apporche de la solution.
    J'ai fait un count($batch) avant l'appel de la méthode HTTPScript j'ai eu 500 après dans le batch si je fais un count de l'array que je récupére j'ai eu comme résultat 499 c'est à dire qu'il y en a un client qui n'a pas était transmit et du coup non traiter!!!
    Est ce normal???

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
  • 81791.16 en réponse à 81791.15 écrit par mamous

    20/11/2013 11:07


    Loïc Couturier
    Rang : Adepte
    Bonjour,

    à quoi sert ceci ?

    $userIdArray = array_slice($_POST['argv'], 1);


    N'est ce pas normal que sur les 500 transmis il n'en reste que 499 si vous couper le tableau ?

    Cordialement
  • 81791.17 en réponse à 81791.16 écrit par Loïc Couturier

    20/11/2013 11:33


    mamous
    Rang : Expert
    Bonjour,

    Oui tout a fait c'était sa le problème , je l'ai modifié et mnt tout fonctionne à merveille merci :)

    Développeur & Intégrateur Web

    RBS Change
    V 3.5.2
    Ecommerce Core
 
Merci de prendre connaissance et de respecter les règles des forums.
 
1453 membres
Aucun membre connecté