IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Exclusion mutuelle pour édition d'un article collaboratif


Sujet :

Langage PHP

  1. #21
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 18
    Points : 26
    Points
    26
    Par défaut
    Pour pallier le problème du blocage infini, il suffirait de limiter le nombre de reports de la fin du blocage dans une variable de session. Via le script Ajax, ce refus de reporter le blocage est détecté : on désactive le textarea et on affiche une erreur dans un div par exemple.

    Je propose la forme suivante pour la variable de session :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $_SESSION['blocages']=array();
    Pour chaque article modifié durant la session, on crée une clé dans ce tableau qui est réinitialisée à 0 chaque fois que l'utilisateur commence à modifier une page. Chaque Ajax incrémente la valeur de cette clé. Ainsi, plusieurs articles peuvent être édités simultanément.

    Au début d'une modification d'article :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $_SESSION['blocages'][$_GET['articleid']] = 0;
    mysql_query("METTRE LA DATE À JOUR POUR L'ARTICLE");
    Le script ajax (lui fournir un paramètre $_GET['articleid']:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if($_SESSION['blocages'][$_GET['articleid']]<720){#une heure d'inactivité
      $_SESSION['blocages'][$_GET['articleid']]++;
      mysql_query("METTRE LA DATE À JOUR POUR L'ARTICLE id=".$_GET['articleid']);
      echo 'ok'; #lu par ajax
    }
    else echo 'erreur!'; #lu par ajax qui désactive le textarea et les boutons Save.
    Il y a même possibilité d'envoyer chaque fois le texte à ajax qui met son md5 dans une variable $_SESSION['memoire'][articleid]. Si l'article est encore en cours de modification (le md5 a changé), on n'incrémente pas la variable $_SESSION['blocage'][articleid].

    Louperivois

  2. #22
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    45
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 45
    Points : 55
    Points
    55
    Par défaut
    Même si ça me tente bien ... je peux en trouver
    Chiche ??

    Ne faudrait il pas un garde fou, un temps Max qui rendra inactif l'Ajax ?
    ... c'est ce que je disais :
    bien évidemment doubler d'un temps d'édition maxi qui libérerait les verrous
    Perso je ne pense vraiment pas qu'il faille se prendre la tête plus qu'il ne faut.

    En blindant tout de même un peu, si cela est réellement nécessaire, ... parce si il y a en moyenne 4 modifs par article et par mois, ça ne sert à rien de se faire chi** à limiter et contrôler trop précisément les temps d'édition, les probabilités n'en valant pas la peine :

    Un utilisateur autorisé édite un article
    => on passe le flag de verrouillage correspondant à l'article à 1 en DB, en renseignant l'ID de la personne qui l'édite et on renseigne le timestamp de début d'édition
    => on affiche un joli message discret "vous ne pouvez pas modifier cet article qui est en cours d'édition par Tartanpion (heure d'édition : HH:mm:ss)" pour les lecteurs
    => côté éditeur, on informe correctement des règles d'édition et des restrictions temporelles, histoire qu'il ne soit pas pris au dépourvu alors qu'il s'arrache les cheveux à tenter de tourner correctement sa phrase

    Un peu plus techniquement :
    un ajax, actif depuis n'importe quel endroit où l'édition est possible, envoi vers le serveur à intervalles réguliers un signe de vie (le navigateur est ouvert sur la page d'édition), un timestamp de l'édition réelle (cad il y a eu des modifications === l'éditeur a entré, supprimé, modifier du texte), et le texte en cours de saisie.
    [pause]
    Tu voulais me taper dessus RunCodePhp ?
    Voilà un bon moyen : "Mais ça va prendre des ressources folles !!!"
    Ben un tio peu (si peu), mais mettre en session le texte entré à intervalles réguliers (ou mieux, uniquement lorsqu'il est modifié) est à mon avis essentiel : rien de pire que d'avoir pris du temps à taper un texte et de tout perdre par une fausse manip' (ou autre)
    [/pause]

    Bref, à partir de ces informations :
    - si plus de signe de vie pendant X secondes => il est parti => on vire, on libère, ...
    - si signe de vie mais pas d'édition réelle pendant un temps X (l'éditeur est parti au bar mais a laissé la fenêtre d'édition ouverte) => on vire (déblocage du flag, patati patata, mais on peut, pourquoi pas, conserver son texte pour une utilisation ultérieure)
    - si signes d'édition réelle (et signes de vie of course) => on prolonge d'autant, faut laisser le temps
    - et bien évidemment, si il arrive à ses fins et click sur "modifier", on update, on libère, et on va boire une bière.

    Heu .... et puis c'est tout, et au fond c'est déjà beaucoup.
    Après on peut toujours pousser bien plus loin, mais bon, faut que ça en vaille la chandelle.

    Bonne fin de soirée à vous,

    Kohntark-

  3. #23
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par Kohntark
    Perso je ne pense vraiment pas qu'il faille se prendre la tête plus qu'il ne faut.
    Et bien pourquoi tu t'es pris autant la tête alors ?

    La bonne solution a déjà été donnée :
    Citation Envoyé par Bebel
    Pour contourner ce problème, tu peux soit mettre un nombre limité de répétition pour l'execution de l'ajax.
    Elle est hyper simple, car il y aura un setTimeout() pour déclencher de manière périodique l'Ajax, et donc il suffit de rajouter 2 variables JS globales : 1 compteur, et un nombre_max
    SI compteur < nombre_max ALORS setTimeout(update_date_edition(), 10000)
    La période où l'Ajax sera déclenchée (ici j'ai mis 10000 ms soit 10 secondes) est connue, le nombre de cycle qu'il faudra lancer (le compteur) sera lui aussi connu.
    nombre_max * 10(secondes) = Temps Max d'édition verrouillé.
    Tout ceci c'est un bon compromis entre un temps trop court pour corriger un article et un temps de verrouillage trop long.

    C'est plus simple, non ?

    De plus, on aura tout le loisir d'avertir l'éditeur que la fin du verrouillage prend fin dans X secondes, voir même mettre un compte à rebours.


    A mon sens, mettre un flag 0 ou 1 c'est casse gueule, car il y aura toujours un risque que cela reste à 1 dans la Bdd, ou alors ça complique les choses.
    Le plus simple, c'est de mettre une date (un champ DATETIME), et ici, la solution qui est de rajouter via Ajax 10-15 secondes (par exemple) au temps en cours à chaque lancement de l'Ajax fera que l'article pourra être édité au-delà de ces 10-15 secondes, dans le cas où l'éditeur quitte l'article, le site, où plus de réseau Internet, panne de courant, etc, etc ...
    Faut juste stopper cet Ajax à un moment donné, le garde fou.

  4. #24
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    45
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 45
    Points : 55
    Points
    55
    Par défaut
    La bonne solution a déjà été donnée :
    Elle est hyper simple, car il y aura un setTimeout() pour déclencher de manière périodique l'Ajax, et donc il suffit de rajouter 2 variables JS globales : 1 compteur, et un nombre_max
    SI compteur < nombre_max ALORS setTimeout(update_date_edition(), 10000)
    La période où l'Ajax sera déclenchée (ici j'ai mis 10000 ms soit 10 secondes) est connue, le nombre de cycle qu'il faudra lancer (le compteur) sera lui aussi connu.
    nombre_max * 10(secondes) = Temps Max d'édition verrouillé.
    Tout ceci c'est un bon compromis entre un temps trop court pour corriger un article et un temps de verrouillage trop long.
    Personnellement je suis contre cette solution et c'est pour cela que je présentais ce que je ferai dans cette situation.
    A mon avis limiter le temps d'édition d'un article est contre productif. Certaines éditions peuvent sans doute mettre du temps, 5, 10 min, (+ ?)
    Que fait l'auteur lorsqu'il voit qu'il n'a plus de temps : il bâcle ? ne se relis pas ? copie son texte, le valide, puis ré édite ? ... beaucoup de manip tout ça, et c'est inconfortable.
    Par ailleurs, et si j'ai bien compris, si l'éditeur part boire une bière l'article reste verrouillé jusqu'à nb max * setTimeout ... pas glop.

    Avec ce que je propose :
    - il a tout le temps qu'il veut dès l'instant où il travaille effectivement sur l'article (ce que j'appelais "édition réelle", que l'on pourrait implémenter avec onKeyUp par ex)
    - s'il s'arrête xx sec on libère l'article directement

    C'est à mon sens bien plus confortable, même s'il est vrai que c'est un peu plus complexe à mettre en place (encore que)

    Je ne suis pas d'accord sur le risque du flag, par contre c'est vrai qu'il ne sert à rien.

    Pour tenter d'être un peu plus clair :
    En DB :
    ID_editeur
    ID_article
    debut_edition
    edition_reelle

    click sur bouton édition :
    ID_editeur => XXX
    ID_article => XXX
    debut_edition => NOW
    edition_reelle => NOW

    Ajax (toutes les 15 sec par ex)
    edition_reelle => NOW
    On peut ici en profiter pour afficher un message : "attention : pas d'activité depuis 45 secondes, l'édition de votre article va prendre fin"

    click sur bouton valider ou (edition_reelle + 60) < NOW :
    edition_reelle => 00/00/00 00:00:00

    Le garde fou repose sur l'édition effective, pas sur un temps arrêté, et il n'y a aucun risque de bloquer un article plus qu'il ne faut.


    Menfin, c'est personnellement ce que je ferai personnellement moi.


    Cordialement,

    Kohntark-

  5. #25
    Nouveau membre du Club
    Inscrit en
    Février 2007
    Messages
    18
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 18
    Points : 26
    Points
    26
    Par défaut
    Relisez mes deux messages, je pense qu'ensemble ils abordent tous les problèmes soulevés. Le compteur de reports (variable session sous forme de tableau pour chaque article modifié) ne s'incrémente simplement pas (ou se réinitialise) si AJAX envoie un texte différent de celui de sa dernière exécution (préalablement stocké dans un autre tableau variable session sous forme de md5). Une fois que le compteur atteint, quoi, 15 minutes d'inactivité, on gèle la zone de texte, on arrête l'exécution d'ajax, on affiche un message d'erreur et on recule le timestamp pour débloquer l'article.

  6. #26
    Membre éprouvé Avatar de Bebel
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2003
    Messages : 786
    Points : 1 262
    Points
    1 262
    Par défaut
    Citation Envoyé par Kohntark Voir le message
    Je ne suis pas d'accord sur le risque du flag, par contre c'est vrai qu'il ne sert à rien.
    S'il y a juste un flag pour bloquer le risque est quand même assez présent. Apres si c'est juste un flag en plus des différents champs d'heure, la il ne sert à rien.

    Mais sans informations complémentaires sur les habitudes des rédacteurs, cela risque de ne pas être évident pour trouver la meilleure solution dans ce cas la.

  7. #27
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Hé, je n'avais pas vu que la discussion s'était poursuivie sur une 2nde page !
    J'ai lu le reste de vos avis. Encore une fois, ça me parait des bonne solutions.

    Le moment de faire un choix étant arrivé, j'ai tranché, avec l'opinion de mon collègue (nous sommes étudiants).
    Ayant peu de temps restant à notre disposition, nous avons choisi la solution la plus simple. Donc pas la meilleure, pas la plus sûre, mais une qui reste correcte.
    Dans la table des articles, deux colonnes : "date_debut_edition" et "editeur_id".

    Lorsqu'une personne va éditer un article pour une première fois, ces valeurs sont mises à jours. Lorsqu'il quitte la page :
    - Pour valider un article (arreter l'édition)
    -> valeurs mises à NULL
    - Pour continuer à éditer l'article, mais sur d'autres page que celles de bases
    -> valeurs remises à jour avec date actuelle
    - Pour aller ailleurs (ou ferme le navigateur)
    -> valeurs mises à NULL

    Dans le dernier cas, on récupère l'événement "onbeforeunload", et on lance un ajax pour aller modifier la BD.

    Si le type s'endort sur son article, il conservera le verrou pendant une heure maxi. Au delà, si qqun essaie d'éditer l'article, il pourra le faire car le délai maximum se sera écoulé. Si l'endormi se réveille, et qu'il veut enregistrer son article, c'est tant pis pour lui (hé oui, pauvre vieux...).

    Donc voilà, ça a plusieurs inconvénients. En particulier, un petit malin peut aussi tricher en essayant de conserver le verrou alors qu'il a quitte la page. Mais ca marchera qu'un heure, après la stratégie du "timeout" évitera le débordement.
    Mais ça avait aussi l'avantage d'être léger et rapide à mettre en oeuvre. Et pour la plateforme sur laquelle on travaille, ce niveau de sécurité nous a semblé acceptable.

    Un grand merci à tous pour vos contributions qui je pense, pourront être utiles à d'autres dans l'avenir.

    Je marque ce sujet comme "Résolu"

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Exclusion mutuelle
    Par Jahjouh dans le forum C++
    Réponses: 4
    Dernier message: 28/11/2005, 21h18
  2. Utiliser un héritage avec exclusion mutuelle correctement
    Par akecoocoo dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 20/11/2005, 22h54
  3. Exclusion mutuelle
    Par Jahjouh dans le forum C++
    Réponses: 15
    Dernier message: 24/09/2005, 12h32
  4. [Thread][Synchronisation] Exclusion mutuelle
    Par masto dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 20/01/2005, 16h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo