Calcul des relations dynamiques

Précision sur le type de lien d'un document à un autre

Actuellement, la gestion des révisions lors du lien d'un document à un autre est mal définie. Nous voulons pouvoir spécifier quelle révision d'un document lié s'applique : soit la dernière, soit une révision spécifique, soit la dernière révision dans un état spécifique (du cycle de vie).

Nom de l'option : docrev (issue http://dev.freedom-ecm.org/issues/638)

Valeurs de l'option :

  • docrev=latest – la révision liée du document est la dernière disponible (défaut)
  • docrev=fixed – la révision liée du document est fixée à la révision initialement liée
  • docrev=state(stateLabel) – la révision liée du document est la dernière disponible du document dans l'état stateLabel (ex: docrev=state(cr_published) pour un lien vers un docid(“MINUTEMEETING”) dans sa dernière révision publiée)

Lien unique d'un document à un autre

Il faudrait pouvoir préciser qu'un document lié au document courant ne peut être lié à un autre document. Cela permet d'éviter de lier, par exemple, un compte utilisateur à deux personnes différentes.

Nom de l'option : unique

Valeurs de l'option

  • unique=no : d'autres documents peuvent référencer le document lié (défaut)
  • unique=yes : le document lié ne peut être lié qu'au document courant

Rafraîchissement des champs calculés des documents liés suite à une modification sur un document

Après modification d'un attribut d'un document, l'ancienne valeur de l'attribut peut continuer à apparaître dans les documents liés via la recherche. A l'ouverture du document lié, les attributs calculés sont recalculés de toutes façons et il n'y a pas de problème dans ce cas.

Nous cherchons donc à pouvoir spécifier, dans les options des attributs calculés d'un document, s'il faut recalculer l'attribut après modification du document lié. Il s'agit d'une option pour éviter d'impacter les performances avec des cascades de modifications hors de contrôle.

Nous prendrons l'exemple de l'attribut SERT_SOC d'un document MINUTEMEETING, calculé suivant la fonction ::getDocValue(SERT_PART, US_IDSOCIETY) dans ecm.ods.

Nom de l'option : refreshOn

Valeurs de l'option : Nous voulons pouvoir spécifier s'il faut recalculer suivant différents critères.

refreshOn Description
SOCIETY.title Si le document pointé est une société et que son titre a changé alors l'attribut courant prend la nouvelle valeur du titre du document pointé
Ceci est aussi applicable aux docid miultiple et aux docid qui sont dans des tableaux
.title Si le document pointé à son titre a changé alors l'attribut courant prend la nouvelle valeur du titre du document pointé
SOCIETY.si_phone Si le document pointé est une société est que son n° de tél a changé alors l'attribut courant prend la nouvelle valeur du n° de tél du document pointé
SOCIETY Si le document pointé est une société et qu'il a été modifié alors la méthode ::refresh() est appelée
.* Si le document pointé a été modifié alors la méthode ::refresh() est appelée
.*::my_method() Si le document pointé a été modifié alors la méthode ::my_method est appelée
or(.title,.lock) Si le titre ou l'état du verrou du document pointé a été modifié alors la méthode ::refresh est appelée
or(.title,SOCIETY.si_phone) Si le titre du document pointé a été modifié ou si c'est une société et que son n° de tél à changé alors la méthode ::refresh est appelée
and(.title,SOCIETY.si_phone) Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::refresh est appelée
and(.title,SOCIETY.si_phone)::my_method() Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::my_method est appelée
and(.title,SOCIETY.si_phone)::my_method(new.si_phone, old.si_phone) Si le titre du document pointé a été modifié et si c'est une société et que son n° de tél à changé alors la méthode ::my_method est appelée avec la valeur modifié de si_phone et l'ancienne valeur

Méthode

Lors d'une modification, noter les champs qui ont changé de valeur (potentiellement durant les appels à $doc→setValue()). À la validation des modifications, ($doc→modify()), lancer en tâche de fond la vérification des modifications potentielles à effectuer sur les documents liés.

Si un ou plusieurs documents liés sont modifiés suite à ce traitement, la même méthode cascadera ces nouvelles modifications sur les documents liés au niveau N+2. Il faut garder trace du nombre d'itérations dans la cascade pour éviter une boucle infinie, et toujours privilégier la vérification des modifications potentielles au niveau N+1 à celle du niveau N+2.

Implémentation

A l'import de famille, il faudra renseigner une table spécifique “docrefreshrule” qui liste les refreshOn, contenant les colonnes suivantes :

  • id
  • id famille concernée
  • id attribut calculé
  • operateur de la condition (optionnel)
  • tableau de conditions sous la forme id_famille.attribut
  • methode

Lors de la modification d'un document, il faudra insérer dans une table de rafraîchissements à effectuer “docrefreshtask” une ligne contenant

  • id document modifié
  • champs modifiés dans le document
  • date de la modification (pour permettre de ne traiter que la dernière modification le cas échéant)
  • niveau de récursion
  • statut de la tâche (nouvelle) pour permettre un rescan de la table.

Traitement des rafraîchissements à faire

Nous nous proposons de déférer les traitements à une instance (par contexte) d'un daemon. Ce daemon sera (re)lancé via cron. C'est ce daemon qui se chargera d'insérer les tâches à effectuer dans la table docrefreshtask. Il sera contacté via une socket TCP par Freedom, qui lui enverra un objet Doc sérialisé. le daemon répond un simple ACK à Freedom, insère les valeurs requises dans la table de tâches, puis s'occupe de traiter les informations reçues dans un autre process :

  • par ordre de niveau de récursion
  • seulement la dernière modification si plusieurs modifications (avec les mêmes attributs modifiés) sont présentes
  • effacement des lignes inutiles selon le précédent critère
  • récupération des documents liés, de leur famille et des règles de refresh de ces familles
  • effacement des lignes inutiles (documents modifiés pour lesquels il n'y a pas de documents liés avec règles de refresh)
  • marquage du statut de la ligne “en cours de traitement”
  • recalcul des attributs calculés de chaque document lié (et après modification, insertion au niveau N+1 dans la table de tâches)
  • effacement des lignes “en cours de traitement”
  • rescan de la table de tâches
  • si elle est vide, retour au mode polling

Ce daemon pourrait être, ou non, déporté sur un autre serveur. Avantages d'un déport : pas d'impact sur la charge du serveur Freedom ; plus grande modularité. Inconvénients d'un déport : ce daemon étant chargé de modifier lui-même des documents, il faudra installer certains modules de Freedom sur l'autre serveur afin qu'il puisse bénéficier des APIs Freedom ; léger lag induit par le réseau ; nécessite de faire écouter PostgreSQL sur une interface externe en plus de l'adresse loopback.

D'autre part, ce daemon pourrait, ou non, utiliser sa propre base de données. Avantages d'une base de données propre : pas d'impact sur la base principale freedom lors du traitement/insertion de tâches. Inconvénients : Nécessite que l'insertion des règles (à l'import de familles) soit faite par le daemon aussi ; nécessite deux configurations de base de données, l'une pour les règles et tâches, l'autre pour la modification des documents Freedom ; si le serveur est déporté, installation et maintenance d'une deuxième instance de PostgreSQL.

Dans une optique de simplicité, on fera tourner le daemon sur le même serveur avec la même base de données.

Tests unitaires

Test pas de refresh

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé (malgré la modification de l'animal lié)

Test refreshOn=ANIMAL sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=ANIMAL.AN_ESPECE sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=ANIMAL.AN_SEXE sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé (pas de refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=ANIMAL.title sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=or(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=or(ANIMAL.AN_PHOTO,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé (pas de refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=and(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé (pas de refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=and(ANIMAL.AN_ESPECE,ANIMAL.AN_SEXE) sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Modifier le sexe de l'animal vers une autre valeur
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)

Test refreshOn=::checkAnimalRefresh() sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer une méthode checkAnimalRefresh() dans Method.Carnet.php qui ajoute une intervention dans le carnet de santé puis renvoie TRUE
  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “antilope” et trouver le carnet de santé précédemment créé (suite au refresh du carnet de santé après modification de l'animal lié)
  • Vérifier la présence de l'intervention ajoutée pour vérifier que la méthode a été appelée

Test refreshOn=::checkAnimalRefresh() sur l'attribut CA_IDNOM de la famille CARNETSANTE

  • Créer une méthode checkAnimalRefresh() dans Method.Carnet.php qui ajoute une intervention dans le carnet de santé puis qui renvoie FALSE
  • Créer un animal dont l'espèce est chat.
  • Créer un carnet de santé à cet animal.
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé
  • Modifier l'espèce de l'animal vers une autre espèce (antilope)
  • Exécuter manuellement le script wsh de refresh
  • Rechercher les carnets de santé avec “chat” et trouver le carnet de santé précédemment créé (pas de refresh du carnet de santé après modification de l'animal lié)
  • Vérifier la présence de l'intervention ajoutée pour vérifier que la méthode a été appelée
freedom_3/workinprogress/compute_dyn_relations.txt · Dernière modification: 02/04/2010 12:08 (édition externe)