sdx-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sdx-users] débrancher la session?


From: Frédéric Glorieux
Subject: Re: [sdx-users] débrancher la session?
Date: Mon, 12 Sep 2005 10:45:50 +0200
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)


Bonjour,

Est-ce qu'il serait possible de débrancher complètement
le mécanisme de session dans SDX (idéalement, au niveau
d'une application; à défaut, au niveau de SDX)?

De manière simple, non, car c'est un fondement applicatif de SDX. Par contre, pour le problème que vous rapportez (et que vous avez déjà très bien décrit), je ne pense pas que la suppression de la session soit une solution, ni non plus que la session pose problème à une solution.

Ce qu'il faut donc, c'est que certaines URI soit mises en cache. Cocoon a un mécanisme natif de cache parfaitement adapté à ce genre de choses (ex: les étapes de transformations dans le pipeline), à la réserve que, par défaut, une page dynamique (XSP) n'est pas mise en cache car Cocoon. Il ne peut savoir par défaut sur quel critère il faudrait sauvegarder ce qui est généré. Cela vous demande de rentrer un peu dans les entrailles de cocoon, soyez certain que ce ne sera pas un mauvais investissement pour vos applications.

Une rare référence sur ce sujet
<http://wiki.apache.org/cocoon/XSPCachingWithCocoonHEAD>
ou les sources des générateurs
peut-être que Sylvain Wallez saura apporter plus de précisions.

L'idée est que, pour cacher un état d'un tuyau (ici le générateur xsp), Cocoon doit avoir un identifiant du XML à sauvegarder, autrement dit, la XSP doit savoir monter une clé unique pour toutes les pages différentes qu'elle peut générer. C'est clairement dépendant de chaque application. Une solution générique au niveau de SDX serait non seulement longue à monter (il faudrait par exemple tenir compte de toutes les bases citées, les paramètres pouvant entrer dans les requêtes, etc), mais en plus, potentiellement sans gros avantage. En effet sur le principe, les requêtes utilisateur sont généralement très variées, SDX n'est pas dimensionné comme un Google qui peut faire des économies d'échelle sur les requêtes souvent demandées.

Deuxième aspect, Cocoon doit savoir jusqu'à quand ce XML caché est valide. En général, il ne l'est plus si l'XSP a changé, ou si d'autres ressources nécessaires ont été modifiées, pour nous, si une base a changé. A ce propos, on a implémenté quelque chose dans la branche HEAD de sdx qui sait dire si une base a été modifiée. En réalité, c'est loin d'être une solution miracle, par exemple, si SDX est utilisé en alimentation continue, les bases changent tout le temps, ce qui fait perdre tout avantage à une cache regénérée à chaque fois. Ce qui m'a réussi à cet endroit, c'est l'action clear-cache, accessible en administration, qui permet de laisser regénérer une page d'accueil à la demande. Selon le process de l'appli, l'xsp peut très bien s'invalider tous les jours, les premiers du matin auront des pages un peu lentes, mais le gain en performance est ensuite énorme. J'ai eu un cas 1 à 2 secondes en génération, 30ms en cache. Pour des tampons de 1 à plusieurs minutes (nécessaire pour site à gros traffic), penser alors plutôt mod_cache Apache, bien documenter sur les listes Cocoon.

Passons à un cas testé

J'ai des ressources indexées dans une arborescence (ex: système fichiers), et je voudrais conserver l'information de cette hiérarchie pour offrir une navigation par dossiers. L'avantage de SDX, c'est que je peux paginer si un dossier contient 2000 ressources, offrir divers filtres. Gros inconvénients de sdx, si j'affiche tous les enregistrements du dossier /dossier/, je les attends dans l'ordre des noms (path=/dossier/001), d'où un "sort" qui peut être très dissuasif.

Le pipeline en sitemap

<!-- directory d'une collection -->
<map:pipeline type="caching">
  <map:match pattern="**dir.xml">
    <map:generate type="xsp" src="{global:actions}dir.xsp">
      <map:parameter name="dir" value="/{1}"/>
    </map:generate>
    <map:serialize type="debug"/>
  </map:match>
</map:pipeline>


Le corps de mon xsp

<sdx:page>
  <xsp:logic>String dir=parameters.getParameter("dir", "/");</xsp:logic>
<sdx:executeSimpleQuery ff="folder" hilite="true" fvString="dir" hppSession="hpp" query="sdxall:1">
    <sdx:sort field="path"/>
  </sdx:executeSimpleQuery>
</sdx:page>

Dans l'état, cela ne peut pas être caché, mais les principe de clé et validité peuvent être implémenté ainsi

<?xml version="1.0" encoding="UTF-8"?>
<xsp:page
  language="java"
  xmlns:xsp="http://apache.org/xsp";
  xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx";
  xmlns="http://www.w3.org/1999/xhtml";
  >
  <xsp:structure>
    <xsp:include>java.text.SimpleDateFormat</xsp:include>
    <xsp:include>java.util.Comparator</xsp:include>
    <xsp:include>java.io.FileFilter</xsp:include>
    <xsp:include>java.util.Arrays</xsp:include>
    <xsp:include>java.net.URI</xsp:include>
    <xsp:include>java.net.URL</xsp:include>
    <xsp:include>org.apache.excalibur.source.SourceValidity</xsp:include>

<xsp:include>org.apache.excalibur.source.impl.validity.AggregatedValidity</xsp:include>

<xsp:include>org.apache.excalibur.source.impl.validity.FileTimeStampValidity</xsp:include>

<xsp:include>org.apache.excalibur.source.impl.validity.ExpiresValidity</xsp:include>
    <xsp:include>org.apache.excalibur.source.Source</xsp:include>
    <xsp:include>org.apache.excalibur.source.SourceResolver</xsp:include>
  </xsp:structure>
  <xsp:logic><![CDATA[

/** l'objet validité agrège le fichier xsp et les bases de l'application */
    AggregatedValidity validity;
    /** The input source, je fais pareil que cocoon */
    protected Source inputSource;

                // Méthode appellée par Cocoon pour voir si cette page est 
encore valide
                public SourceValidity getValidity() {
      // Si validité déjà construite, la retourner, sinon la faire
      if (this.validity != null) return this.validity;
      else  try {
// la validité doit dire, regénérer si l'une des bases a changé, et si le fichier xsp a changé
          validity=new AggregatedValidity();

// ici, il faut mettre le chemin de son xsp, relativement au sitemap
          // coocon a l'air de bien résoudre les path
          inputSource = super.resolver.resolveURI("actions/dir.xsp");
// pour bien vérifier que cocoon arrive à faire un FileTimeStampValidity,
          // donc que c'est le bon fichier
          // System.out.println(this.inputSource.getValidity());
          validity.add(this.inputSource.getValidity());

          // validité de l'application
          // à noter, on peut probablement s'en passer,
          // dès lors que la page d'administration fait un clear-cache

          // le répertoire de l'application en cours
Enumeration enum = new java.util.StringTokenizer (request.getServletPath(), "/");
                                  String 
app=((java.util.StringTokenizer)enum).nextToken();
                                  // permet de vérifier que l'on cherche dans 
la bonne appli,
// permet de vérifier que la méthode est appelée ( !! <map:pipeline type="caching"/> !!)
                                  // System.out.println(app);
validity.add( ( (FrameworkImpl)manager.lookup( Framework.ROLE )).getApplicationByPath(app).getSourceValidity());


          return this.validity;

        }
        catch ( Exception e ) {
          return null;
        }
      return null;
                }

                // Méthode pour identifier cette page dans la gestion de la 
cache
                // le point critique
                
                public Serializable getKey()
                {


      // le qid n'a aucun intérêt pour faire une clé de cache
      // puisque relatif à l'utilisateur
      // l'intitulé de requête n'est pas optimal, mais bon
      // par contre il faut absolument le repasser de page en page

      String q=request.getParameter("q");
      if (q!=null && !"".equals(q)) q="&q="+q;
      else q="";

      // une page différente par page de navigation demandée

      String p=request.getParameter("p");
      if (p!=null)p="&p="+p;
      else p="";

      // différence selon le nombre de résultats par page

      Session session=request.getSession();
      String hpp=request.getParameter("hpp");
if (hpp == null && session != null) hpp=(String)session.getAttribute("hpp");
      if (hpp != null) hpp="&hpp="+hpp;
      else hpp="";


      // la clé est construite comme une pseudo URI relative à cocoon

      String key= request.getRequestURI() + q + p + hpp;
      // pour deboguage, permet de vérifier sa clé
      // System.out.println(key);
                        return key;
                }

  ]]></xsp:logic>
  <sdx:page/>

En souhaitant que cette proposition vous donne des idées.

Évidemment on peut ne pas utiliser les sessions sans les
débrancher, mais alors elles sont créées quand même, etc.,
donc il serait plus intéressant de "couper le circuit",
si c'est possible: l'est-ce?

Cdt,
EB


--- explication de la demande ---

Outre la gestion des utilisateurs, la session fournit
surtout la mise en cache des résultats de requête, de
sorte que les pages successives d'une requête ne donnent
pas lieu à une nouvelle recherche.

Elle est utilisée aussi pour le hilite et le parcours
du jeu de résultat (de résultat en résultat).

Toutefois, dans plusieurs applications les requêtes
toujours identiques (lancées par des liens) représentent
plus de 95% des requêtes par rapport aux vraies recherches;
dès lors il semble plus intéressant de cacher la totalité
des pages de la requête pour tous les utilisateurs, que
les résultats de chaque requête de chaque utilisateur.

Par exemple, (à corpus identique) la page
        rech.xsp?q=toto&p=27
ne change jamais (durée de validité=durée de vie du corpus),
tandis que la page
        rech.xsp?qid=sdx_q3&p=27
est différente pour chaque utilisateur, expire, est
recréée, etc.

De plus, pour les mêmes raisons, la première url peut
être bookmarquée et restera toujours valide, tandis que
la seconde ne peut pas l'être, et si elle l'est ramènera
sur une page vide.

Pour le reste:
- la navigation de résultat en résultat est peu utilisée
  (dans mon expérience) car les utilisateurs n'y sont pas
  habitués
- la gestion des utilisateurs est rarement nécessaire;
- seul le hilite serait intéressant à conserver mais il
  y a peut-être un autre moyen (utiliser directement
  les termes présents dans les paramètres de requête?)
- ... autres utilisations de la session?





_______________________________________________
sdx-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/sdx-users




--
Frédéric Glorieux (AJLSM, http://ajlsm.com)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]