Tips & Tricks

 

AOLserver cannot handle URLs with "+" and does not ns_urlencode them correctly. 

Therefore you can make use of this patch and add 

regsub -all {+} $my_url {%2b} my_url 

To your code after ns_urlencoding it.

Performance Tuning

To gather some statistics you migh want to enable the stats mode: 

ns_section "ns/server/stats" 

     ns_param enabled 1 

     ns_param url "/_stats" 

     ns_param user "aolserver" 

     ns_param password "stats" 

Then take a look at the "Process" and "Threads" sections. 

Compile ns_oracle with 10g

 

In order to install ns_oracle along with AOLserver you will first have to install the Oracle 10g Client.

Then follow the AOLserver installation instructions.

After that, go to /usr/local/src/aolserver45 and install nsoracle.

cd /usr/local/src/aolserver45
cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nsoracle 
cd nsoracle

The Makefile needs to be changed. Here are the changes that I have made:

47c47
< ORA_VERSION=$(shell grep OCI_LOGON2 $(ORACLE_HOME)/rdbms/demo/oci.h)
---
> ORA_VERSION=$(shell grep OCI_LOGON2 $(ORACLE_HOME)/rdbms/public/oci.h)
53c53
< MODLIBS  =  -L$(ORACLE_HOME)/lib -lclntsh -lcore9 -lcommon9 -lgeneric9 -lclient9
---
> MODLIBS  =  -L$(ORACLE_HOME)/lib -lclntsh -lnnz10 -locixe
67c67
< include $(NSHOME)/include/Makefile.global
---
> include  $(NSHOME)/include/Makefile.module

Once this is done you can run and install it with

make install NSHOME=/usr/local/aolserver

Now you only have to add your wrapper script for AOLserver. Create in $(NSHOME) (normally /usr/local/aolserver/bin/) the file nsd-oracle

vi /usr/local/aolserver/bin/nsd-oracle

And add the following two lines

source /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/bin/oracle_env.sh
 export NLS_DATE_FORMAT="YYYY-MM-DD"
 exec /usr/local/aolserver/bin/nsd $*

Use nsd-oracle to start your AOLserver in the future. 

 

ADP caching 

There's a new, undocumented and lightly tested ADP caching mechanism in the head version of the code.   It works by caching results of page executation on an ADP include with ns_adp_include.   Simple usage would be: 

ns_adp_include -cache ttl file 

where ttl is an Ns_Time object (or just a number of seconds).   Everything in 

the top level file and all included files below will be cached for the given time unless a lower level include has some other ttl or a -nocache to disable caching for that file, e.g. with: 

ns_adp_include -cache 10 cachethis.inc 

and within cachethis.inc you have: 

ns_adp_include -nocache personalizedstuff.inc 

then everything execept the personalized stuff would be cached for 10 

seconds. 

The key code is AdpRun in nsd/adpeval.c.    Basically when caching, the results for executing text, script, text, script, ... chunks are saved for later requests as a single text block or at least fewer script blocks if lower level files are not cached.   The usage may be a bit confusing and it caches around files, not strings, but the results are promising in tests we've done.   In the limiting case of caching everything in an ADP file and below, you can turn multi-second database driven responses into quick single-string copy responses which generally respond in milliseconds.

 

Detect application level leaks

 

Script by Gustav Neumann to detect application level leaks:

 # script to determine application level leaks

 # -gustaf neumann

  proc report {} {

    set ps [exec ps xv | grep "^[pid] "]

    set vsz [lindex $ps 6]

    set result ""

    array set total {vars 0 procs 0 cmds 0 array_elements 0 var_bytes 0}

    set details [lindex [__report__ns ::] 0]

    foreach l $details {

      array set tmp $l

      foreach e [array names total] {incr total($e) $tmp($e)}

      append result $l\n

    }

    return "$result\nTOTAL: pid [pid] vsz $vsz namespaces [llength

$details] [array get total]"

  }

  proc __report__ns {ns} {

    if {$ns eq "::dom::domNode" ||

    $ns eq "::dom::domDoc"} {

      set result [list [list ns $ns]]

    } else {

      set pattern [expr {$ns eq "::" ? "::*" : "${ns}::*"}]

      set nrvars [llength [info vars $pattern]]

      set elements 0

      set bytes 0

      foreach var [info vars $pattern] {

    if {[array exists $var]} {

      incr elements [array size $var]

      foreach e [array names $var] {incr bytes [string length ${var}($e)]}

    } else {

      incr bytes [string length $var]

    }

      }

      set nrprocs [llength [info procs $pattern]]

      set nrcmds [llength [info commands $pattern]]

      incr nrcmds -$nrprocs

      set result [list [list ns $ns vars $nrvars procs $nrprocs cmds

$nrcmds \

                array_elements $elements var_bytes $bytes]]

    }

    foreach nc [lsort [namespace children $ns]] {

      if {$nc eq "::xotcl::classes"} continue

      foreach l [__report__ns $nc] {eval lappend result $l}

    }

    return [list $result]

  }

  ns_log notice [report]