cocoon-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jasha Joachimsthal <j.joachimst...@onehippo.com>
Subject Re: thought I had fixe it
Date Mon, 24 Oct 2011 17:17:55 GMT
On 24 October 2011 18:55, Leszek Gawron <lgawron@apache.org> wrote:

> Hello,
>
> @Jasha: advising a user to limit the amount of data usually does not work.
> :)


You can tell the user his search query has a result of 25000 items but I
guess he doesn't want them all in 1 screen. Postprocessing that amount of
items can be tried but many have failed before...


>
>
> On 2011-10-24 18:29, Paul Joseph wrote:
>
>> Actually the real reason is that the user is using a query that required
>> crafting to return 25K results.  He is seeking to show the system "does
>> not scale."
>>
>> Actually I am using in my XML template, a cocoon flowscript repeater
>> widget that does paging.  But this is well after the Java logic has
>> built the large array of results (the array results and the vector
>> secureResults below)
>>
>
> I suspect what might be the problem:
>
> 1. Are your continuations session bound? They are not by default - even
> though you set a short session expiry time most of the data is still held by
> continuations which are being expired with totally different mechanism.
> Container bound continuations are useful in only one case: you build a
> session-less site. For "session" exprience ALWAYS use
> session-bound-continuations.
>
> 2. Your flowscript continuation probably holds the ENTIRE rowset and will
> hold it until it expires (and all children expire). You are not supposed to
> put heavyweight object into your continuation.
>
> Your solutions are:
>
> a. use a generator instead of flowscript. Implementing own generator is
> actually dead easy. Style your data with XSLT.
>
> b. make flowscript "forget" the data after the report has been rendered.
> You probably regenerate your rowset with each request anyway.
>
> This one is actually also easy. This is an example of my production code:
>
>  /* TEMPLATE
>>        var config = {
>>                defaultOrderBy: "name",
>>                defaultDirection: "asc",
>>                valueListProvider: cocoon.getComponent( "valueListBeanName"
>> ),
>>                filterModelName: "filterModel",
>>                viewName: "viewName",
>>                errorRedirect: "/",
>>                rowSelectionReturns: false,
>>                bizData: bizData,
>>                selections: selections,
>>                formHandler: function ( action, bizData ) {
>>                },
>>                rowHandler: function( id, action, bizData ) {
>>                }
>>        }
>> */
>> function sortedFilteredView( config ) {
>>        var defaultMaxResults = new Integer( 100 );
>>        var modelName = ( config.filterModelName != undefined ) ?
>> config.filterModelName : config.viewName;
>>        var form = new Form( "cocoon:/form-def/" + modelName );
>>        //form.createBinding("cocoon:/**form-bind/" +
>> config.filterModelName );
>>
>>        form.locale = determineLocale();
>>        var model = form.getModel();
>>
>>        var bizData = ( config.bizData != undefined ) ? config.bizData :
>> new java.util.HashMap();
>>        model.orderBy = config.defaultOrderBy;
>>        model.direction = ( config.defaultDirection != undefined ) ?
>> config.defaultDirection : "asc";
>>        model.maxResults = ( config.maxResults != undefined ) ?
>> config.maxResults : defaultMaxResults;
>>
>>        if ( config.formInitializer != undefined ) {
>>                config.formInitializer( model );
>>        }
>>
>>        model.skipResults = new Integer( 0 );
>>        while ( true ) {
>>                model.pageNo = new java.lang.Integer( model.skipResults /
>> model.maxResults + 1 );
>>                var filterContext = Packages.org.apache.cocoon.**
>> forms.util.**ContainerWidgetAsMap( form.form );
>>                var items = config.valueListProvider.**generateResults(
>> filterContext, bizData );
>>
>>                var totalItemCount = config.valueListProvider.**countEntries(
>> filterContext, bizData );
>>                var pageCount = new java.lang.Integer( java.lang.Math.ceil(
>> totalItemCount / model.maxResults ) );
>>                var firstPage = ( model.skipResults == 0 );
>>                var lastPage = ( model.skipResults + model.maxResults >=
>> totalItemCount );
>>
>>                form.showForm(  "form/" + config.viewName,
>>                                                {       items    : items,
>>                                                        orderBy  :
>> model.orderBy,
>>                                                        direction:
>> model.direction,
>>                                                        maxResults:
>> model.maxResults,
>>                                                        pageNumber:
>> model.pageNo,
>>                                                        pageCount:
>> pageCount,
>>                                                        firstPage:
>> firstPage,
>>                                                        lastPage :
>> lastPage,
>>                                                        viewConfig: config,
>>                                                        startIndex:
>> ((model.pageNo - 1) * model.maxResults + 1),
>>                                                        bizData  : bizData,
>>                                                        selections:
>> config.selections },
>>                                                        function() {
>>                                                                delete
>> items;
>>                                                        }
>>                                                 );
>>
>>                if ( form.submitId == "finish" ) { //search
>>                        model.skipResults = new Integer( 0 );
>>                } else if ( form.submitId == "cancel" ) {
>>                        return null;
>>                } else if ( form.submitId == "next" ) {
>>                        model.skipResults = new Integer( model.skipResults
>> + model.maxResults );
>>                } else if ( form.submitId == "prev" ) {
>>                        model.skipResults = new Integer( model.skipResults
>> - model.maxResults );
>>                        if ( model.skipResults < 0 )
>>                                model.skipResults = new Integer( 0 );
>>                } else if ( form.submitId == "first" ) {
>>                        model.skipResults = new Integer( 0 );
>>                } else if ( form.submitId == "last" ) {
>>                        model.skipResults = new java.lang.Integer( (
>> java.lang.Math.ceil( totalItemCount / model.maxResults ) - 1 ) *
>> model.maxResults );
>>                } else if ( form.submitId == "changePage" ) {
>>                        if ( model.pageNo != null ) {
>>                                var skipCount = ( model.pageNo  - 1 ) *
>> model.maxResults;
>>                                        if ( skipCount < totalItemCount )
>>                                                model.skipResults = new
>> Integer( skipCount );
>>                                        else
>>                                                model.skipResults = new
>> java.lang.Integer( ( java.lang.Math.ceil( totalItemCount / model.maxResults
>> ) - 1 ) * model.maxResults );
>>                                        if ( skipCount < 0 )
>>                                                model.skipResults = new
>> Integer( 0 );
>>                        }
>>                } else if ( form.submitId == "changeMaxResults" ) {
>>                        model.skipResults = new Integer( 0 );
>>                } else if ( form.submitId != null ) {
>>                        if ( form.submitId == "selectRow" &&
>> config.rowSelectionReturns == true )
>>                                return model.rowId;
>>                        if ( config.rowHandler != undefined && model.rowId
>> != null )
>>                                config.rowHandler( model.rowId,
>> form.submitId, bizData );
>>                        if ( config.formHandler != undefined && model.rowId
>> == null )
>>                                config.formHandler( form.submitId, bizData
>> );
>>                }
>>                if ( model.maxResults <= 0 )
>>                        model.maxResults = defaultMaxResults;
>>                model.rowId = null;
>>        }
>> }
>>
>
> The code is responsible for showing a pageable sortable filterable rowset.
>
> The most important part is :
>
> var items = config.valueListProvider.**generateResults( filterContext,
> bizData );
>
> This object is VERY heavy (it might any row count you might like).
>
> The next important thing is after rendering this object is deleted:
>
>                 form.showForm(  "form/" + config.viewName,
>>                                                {       items    : items,
>>                                                        orderBy  :
>> model.orderBy,
>>                                                        direction:
>> model.direction,
>>                                                        maxResults:
>> model.maxResults,
>>                                                        pageNumber:
>> model.pageNo,
>>                                                        pageCount:
>> pageCount,
>>                                                        firstPage:
>> firstPage,
>>                                                        lastPage :
>> lastPage,
>>                                                        viewConfig: config,
>>                                                        startIndex:
>> ((model.pageNo - 1) * model.maxResults + 1),
>>                                                        bizData  : bizData,
>>                                                        selections:
>> config.selections },
>>                                                        function() {
>>                                                                delete
>> items;
>>                                                        }
>>                                                 );
>>
>
> There is a parameter for cocoon.sendPageAndWait which is not widely known:
> a cleanup function.
>
> http://cocoon.apache.org/2.1/**userdocs/flow/api.html#cocoon<http://cocoon.apache.org/2.1/userdocs/flow/api.html#cocoon>
>
> So your code has to look something like that:
>
> var report = generateYourHorriblyBigReport(**);
>
> cocoon.sendPageAndWait( "myreport.html",
>                        { report: report },
>                        function() {
>                           delete report;
>                        }
>                       );
>
>
>
> I advice you to use some kind of profiler. Money spent on YourProfiler
> might be one of best spent dollars. You can:
>
>  - make a memory snapshot
>  - do your request
>  - make a subsequent memory snapshot
>  - compare both snapshots: there should be NO significant memory
> consumption difference.
>
> HTH
>
>        lg
>
> --
> Leszek Gawron                            http://lgawron.posterous.com
>
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.**apache.org<users-unsubscribe@cocoon.apache.org>
> For additional commands, e-mail: users-help@cocoon.apache.org
>
>

Mime
View raw message