2012-05-14 21 views
8

Sto costruendo un'applicazione web Wicket che dovrà gestire molte richieste simultanee. Ho configurato un ambiente di test e alcuni script jmeter per eseguire il test di caricamento e ho notato che posso ridurre la CPU e l'impronta di memoria della mia applicazione se realizzo la maggior parte delle pagine Stateless.Come posso rendere Stateless "AjaxLink" di Wicket?

Ho aggiunto il codice al metodo onBeforeRender() della pagina più grande per mostrarmi quale dei componenti sta causando lo stato della mia pagina. Questo è il codice che ho per rilevare che:

@Override 
protected void onBeforeRender() {  
    if (!getSession().isTemporary()) { 
     visitChildren(Component.class, new IVisitor<Component>() { 
      @Override 
      public Object component(Component component) { 
       String pageClassName = AbstractStatelessBasePage.this.getClass().getName(); 
       if (!component.isStateless()) { 

        String msg = pageClassName+" is stateful because of stateful component " + component.getClass().getName() + " with id " + component.getId() + "."; 

        List<IBehavior> behaviourList = component.getBehaviors(); 
        for (IBehavior iBehavior : behaviourList) { 
         if (!iBehavior.getStatelessHint(component)) { 
          msg += "\n\t" + "The component has stateful behaviour: " + iBehavior.getClass().getName(); 
         } 
        } 
        LOG.error(msg); 
       } 

       checkedPages.add(pageClassName); 
       return CONTINUE_TRAVERSAL; 
      } 
     }); 
    } 
} 

Nell'output vedo che il comportamento stateful è causato da AjaxLinks utilizzati da alcuni dei componenti esistenti nelle pagine:

ERROR - AbstractStatelessBasePage$1.component(45) | HomePage is stateful because of stateful component InfoGrid$InfoButton with id infoButton. 
    The component has stateful behaviour: org.apache.wicket.ajax.markup.html.AjaxLink$1 

ho ho provato ad aggiungere i metodi getStatelessHint() restituendo "true" in alcuni punti, ma sembra che non aiuti. Ho anche controllato il codice sorgente di Wicket di AjaxLink, le sue superclassi e qualche codice circostante, ma non riesco a capire perché AjaxLink abbia bisogno di essere stato in tutti i casi.

Nel mio caso, AjaxLink si trova in una pagina altrimenti stateless e il collegamento non memorizza lo stato. Come posso far capire a Wicket che questo AjaxLink può essere apolide?

Grazie per il vostro aiuto, Rolf

Edit: accettato risposta funziona con Wicket 1.4.19.

aggiunto il seguente alla pom.xml Maven:

<dependency> 
    <groupId>com.jolira</groupId> 
    <artifactId>wicket-stateless</artifactId> 
    <version>1.0.8</version> 
</dependency> 

Modificato tutti i componenti che si estendevano "AjaxLink" estendere "StatelessAjaxFallbackLink".

Non dimenticate di aggiungere il seguente alla classe WicketApplication, che vi farà risparmiare un po 'di tempo di risoluzione dei problemi:

@Override 
protected IRequestCycleProcessor newRequestCycleProcessor() { 
    return new StatelessWebRequestCycleProcessor(); 
} 

prega di notare che StatelessForm e altre cose senza stato non funziona all'interno di un ripetitore (come " ListView ") per qualche motivo.

risposta

10

La pagina diventa statica quando si aggiunge un comportamento Ajax (AjaxLink utilizza AjaxEventBehavior). Questo perché quando fai clic su un collegamento, Wicket tenta di trovare l'istanza della pagina sul server, quindi trova il componente di collegamento al suo interno e infine esegue il suo metodo di callback, ad es. al clic(). Senza memorizzare la pagina non c'è modo di trovare l'istanza di comportamento ajax ed eseguire il suo metodo di callback.

È possibile utilizzare i comportamenti e i componenti Ajax di Jolira (https://github.com/jolira/wicket-stateless).Lavorano un po 'diverso - quando si fa clic su AjaxLink di Jolira la chiamata Ajax crea una nuova istanza della pagina, trova lo StatelessAjaxLink appena creata in essa, esegue il suo metodo di callback, utilizza infine AjaxRequestTarget per aggiungere componenti/javascript per la risposta Ajax e scarta l'istanza di pagina appena creata (è raccolta dati inutili). La prossima richiesta Ajax fa lo stesso con un'istanza di pagina completamente nuova.

Si potrebbe chiedere: "Perché il codice di Jolira non è nel nucleo Wicket?" - perché dà una soluzione parziale. Ad esempio: facendo clic su statelessAjaxLink1 crea una nuova pagina, esegue onClick() sulla nuova istanza di StatelessAjaxLink dove PanelA viene sostituito con PanelB e aggiunge questo pannello (PanelB) a AjaxRequestTarget. In breve: facendo clic su questo link si sostituisce il corpo di un pannello nella pagina. Se PanelB ha uno StatelessAjaxLink2 all'interno di se stesso, allora questo link non è raggiungibile. Perché ? Perché facendo clic su di esso verrà creata una nuova istanza della Pagina e questa nuova istanza avrà PanelA, non PanelB, e quindi non c'è modo di trovare StatelessAjaxLink2 per eseguire il suo metodo onClick().

Se lo scenario è abbastanza semplice e componenti di Jolira coprire le casi poi li usano. Basta essere consapevoli che uno scenario più complesso potrebbe fallire.

+0

In realtà sostituisco i pannelli, ma lo registro all'interno della sessione, così quando istanziando la pagina posso istanziare i pannelli corretti "sostituiti". Questo sposta lo stato dalla pagina alla sessione. – Rolf

+0

Jolira's StatelessAjaxFallbackLink ha risolto il problema che ho indicato nella mia domanda originale. In questo momento sto incontrando problemi con Stateless all'interno di ripetitori, in cui Wicket non riesce a capire quale componente targetizzare. Ciò potrebbe causare una nuova domanda :-) – Rolf

+0

C'è qualcosa per Wicket 6.10? –

3

C'è un codice per uno stateless AjaxFallbackLink riferito allo wicket wiki e un progetto github correlato a cui è possibile accedere ai seguenti collegamenti da lì. Non sono sicuro che questo risolva completamente il tuo problema, ma potrebbe essere almeno istruttivo.

Un approccio simile è stato provato per wicket 6, ma l'autore avverte che è sperimentale. Il codice è here. Non ho provato a usarlo e quindi non posso garantire per questo.

+0

C'è qualcosa per Wicket 6.10? –

+0

@Hendy Irawan - Guarda il mio aggiornamento! –