Forum OpenACS Q&A: returning pages in "chunks"

Posted by Dirk Gomez on
I have a large page whose loading takes a few seconds and I want it to
return in "chunks" so that the user doesn't have to wait for the
complete page to be returned after about 30 seconds. Is there any
simple (or not so simple) solution to that?
Posted by Antonio Laterza on
what type of page? If your page contain table you should split the table.
Posted by Dirk Gomez on

Hmm, I think my question is not specific enough ;)

The problem at hand is...I have a big database query that takes some time. The user doesn't get to see anything till the tcl page has run through. Then ad_return_template is being invoked and the html is being generated.

I want that "one-off" thing to be broken down into chunks, ideally like this:

  • return some information
  • loop through the database query's result and return it in chunks
  • return some more information.
Posted by Sarah Ewen on

I wanted to do something similar to this when I was writing a wizard-style script to auto-mount new instances of certain packages.

I took a leaf out of the ACS installer script, and ditched ad_return_template.

ns_write is your friend 😊.

Posted by Dirk Gomez on
Uh, some more information I forgot. The style of the "header" and "information" is to be fetched from the corresponding adp file, so it is (unfortunately ;) not possible to use ns_write exclusively.

Please post your code.

Posted by Simon Buckle on
You could try embedding your tcl directly in the adp page. Have a look at [1].


Posted by David Walker on
You can split your template into 2 pieces and call "ns_adp_parse -file filename" for each piece.
ns_write [ns_adp_parse -file /path/to/top_half.template.adp]
ns_write "the long stuff here"
ns_write [ns_adp_parse -file /path/to/bottom_half.template.adp]
Posted by Tom Jackson on

Does this work with the request processor in ACS? I didn't think that it did. I also remember aD deciding that ns_write was too expensive to use. If you do get this to work with the ACS, remember to call db_release_unused_handles just before you call ns_write. Otherwise you could use up all you db handles on a few slow clients.

Posted by Andrew Piskorski on
Tom, sure, it works. You'll want to use template::adp_parse rather than ns_adp_parse, though.

Then you just have to make sure you split up all the master templates you're going to be calling into separate "top" and "bottom" templates. E.g., for the typical case where you have a master for your package, and then a site-wide default-master as well, you'd have something like:

In /packages/my-package/www/my-page.tcl:

set this_dir [file dirname [ad_conn file]]
set template_file "$this_dir/master-top"
set template_top [template::adp_parse $template_file [list title $title context_bar $context_bar]]

In /packages/my-package/www/master.adp:

<include src="master-top" title="@title@" context_bar="@context_bar@">


<include src="master-bottom" right_side_sig="@right_side_sig@">

In /packages/my-package/www/master-top.adp:

<master src="/www/default-master-top">
<property name=focus>@focus@</property>
<property name=title>@title@</property>
<property name=context_bar>@title@</property>



You get the idea... Only mildy annoying to do, at worst.

Posted by Don Baccus on
This is not a change we'll want to make standard, though.  It would be
nice to have a way to tell the template parser to put out the page in "chunks", but in the normal case we don't want to do this.

As Tom mentioned, ns_write is *expensive*.  In a test I did a very long time ago (a couple of years ago) I was able to triple the throughput of pages out of my old P200 box by assigning data gotten from the db to a "page" string variable later returned by ns_return,
vs. using ns_write to put the data out a row at a time.