ampools C and Tcl module for AOLserver 4.5+

Overview

AOLserver allows you to configure separate pools for processing connection requests.  You can designate (register) certain urls to be processed by a particular pool.  You can then configure certain thread parameters for each pool.  In AOLserver 4.0 this was accomplished via config file settings.  In AOLserver 4.5, a Tcl API (ns_pools and ns_limits) is provided instead with no built-in mechanism for pool configuration via config file settings.  In AOLserver 4.5.1, pools.tcl is bundled which can only set up the default pool settings and limits based on config file settings but not any additional pools. (For 4.5.2, we've enhanced pools.tcl slightly to support error pool configuration parameters.)

This module, among other things, allows any number of pools and corresponding limits to be configured based on config file settings. Note that technically pools and limits are not really coupled together.  A limit-set can have different urls registered to it from a pool.  However, we simplify and limit-sets are configured with the same name and registered for the same urls as the pools.

Because threads in a particular pool are dedicated to that pool, it is advantageous to set aside a pool for processing requests for resources that do not require the memory overhead of a Tcl interpreter. To accomplish this, you have to assure that no Tcl filters that might otherwise be registered on this url are executed. This module relies on a patch to AOLserver 4.x (which we include in 4.5.2) (RFE 1012103) that provides an ns_register_filter_shortcut command to configure the urls in the pool to skip the filters as specified (see below for details).

We also provide an ns_register_filter_error  command, which if used with the 'trace' when, will prevent access logging for the url if you don't need it. This, again, can be controlled with config file settings for the pool.

AOLserver 4.5 introduced built-in on-the-fly gzip compression, however, no facility was provided to enable or disable gzip compression outside of ADP pages (RFE 1828471).  In the future, we expect this facility to be exposed as ns_conn compress but in the mean time we provide the am_conn_compress command as a wrapper to Ns_ConnSetGzipFlag.

The ability to enable compression using this command is useful for registered procedures but for static resources served by a dedicated pool with lightweight threads, you need to be able to turn on gzip compression without a Tcl filter. On the other hand, you don't want to compress non-compressible files such as images or .zip files.  Plus for larger, heavily accessed resources such as Javascript files, it is best to serve pre-compressed versions that exist on the file system.  This module allows you to enable and configure compression aspects for urls in a pool via config file settings or manually by using the am_registerGzFileFilter command.

Note that on-the-fly compression for fastpath (i.e. static file) urls requires our 4.5.2 version of AOLserver.

Finally, this module registers Tcl allocate/deallocate traces that update the name of the thread (whether it's a conn, scheduled or job thread) to include the virtual server name it's currently running under to make server log entries and /_stats thread list easier to use.

Installation
Installation is the same as for any other AOLserver module: place the compiled ampools.dll and ampools.so into the bin directory and in the config file under ns_section "ns/server/$server/modules" add as the last module (including after all Tcl modules):
ns_param ampools ${bindir}/ampools.so

Place the tcl file into /modules/tcl/ampools so that it gets sourced when the C module is loaded.  Add configuration parameters as described below. Restart AOLserver, check server log for notices regarding pool setup and configuration.

Configuration Parameters

We recommend that you enable gzip compression by default globally on all GET and POST requests (whether they be ADP, registered procs or fastpath static resources) as follows (these are the default settings in the AM standard 4.5.2 config.tcl):

ns_section "ns/server/$server"
ns_param gzip 	   true   ;# Server default. False will disable all gzipping,
                          ;# enabling gzip at runtime will have no effect
ns_param gzipmin   1024   ;# Minimum content size in bytes to enable gzipping
                          ;# (server default is 4096)
ns_param gziplevel 4      ;# Gzip compression level - server default is optimal
ns_param gzipall   true   ;# Enable compression on all GET and POST requests

ns_section "ns/server/$server/fastpath"
ns_param direct	   false  ;# New in 4.5.2. Normally fastpath bypasses
                          ;# text content encoding and gzip compression.
                          ;# False will allow fastpath and ns_returnfile to
                          ;# perform on-the-fly compression (and encoding)
                          ;# except when fastpath cache is disabled or the file
                          ;# size exceeds cachemaxentry (which by default is
                          ;# 1/10th of cachemaxsize (which defaults to 5000 KB)).

Setup one or more pools with a name and an optional description:

ns_section "ns/server/$server/pools"
ns_param fastpathGzip "Static resources, no Tcl, no Auth,\
                        .gz file or on-the-fly Gzip for text formats"

Note that in AOLserver 4.5+, pools are shared across all virtual servers, so while it is possible to register different urls (with their respective compression settings) in different virtual servers into the same pool, all other configuration parameters except for skipfilters will apply globally and the settings of the last virtual server to be initialized will overwrite prior settings.  So, make your pool names unique across all virtual servers if you want them to be separate.

Configure each pool you setup (parameters with their defaults (except for example maps) are below):

ns_section "ns/server/$server/pool/fastpathGzip"
ns_param MinThreads 0
ns_param MaxThreads 10
ns_param MaxConns 0 ;# or ConnsPerThread, i.e. after how many requests processed
                    ;# by a given thread should it be destroyed, 0 means never.
ns_param ThreadTimeout 120 ;# destroy a thread after this many idle seconds
ns_param MaxWait 100 ;# max number of threads waiting to be serviced
ns_param MaxWaitTime 60 ;# seconds to timeout while waiting to be serviced
ns_param MaxUpload [expr 10*1024*1024] ;#10MB - max bytes in a POST or PUT request
ns_param skipfilters {prequeue preauth postauth trace void nslog}
ns_param map {GET /*.js "gz" "gzip"} ;# serve .gz if present or on-the-fly gzip
ns_param map {GET /*.css "" "gzip"}  ;# don't look for .gz, on-the-fly gzip
ns_param map {GET /*.xsl "" "gzip"}
ns_param map {GET /*.gif "" "none"}  ;# disable compression
ns_param map {GET /*.jpg "" "none"}
ns_param map {GET /*.png "" "none"}

# Other configuration examples:
#ns_param map {GET /resources} ;# use global on-the-fly compression settings
#ns_param map {GET /largedocs "gz" "none"} ;# serve .gz if present but no
                                           ;# on-the-fly compression

Note that skipfilters parameter above which is a list of filter whens that should be skipped.  This is especially useful if you have a global authentication/personalization Tcl filter on /.  Keep in mind that this will skip all filters at that when, including C filters.

There are also special keywords supported in skipfilters - void and nslog.  There is not actually such a when as supported by ns_register_filter.  void refers to traces registered with ns_register_trace (known internally as void_trace) and nslog to C-level ServerTraces currently only used by the nslog access logging module.  Because of current limitations in AOLserver APIs, if you specify void or nslog then all three post-close events will be skipped: traces (i.e. filters registered with ns_register_filter trace), void_traces and nslog access logging.

Each url registration map parameter is a list with at least 2 and up to 4 elements:

  1. Method (i.e. GET, POST, PUT)

  2. Url (use ns_register_proc format, not ns_register_filter format)

  3. Extension of a pre-compressed file in the same directory as the requested file to send instead (i.e. specify "gz" here and a request for /inc/amutils.js will send /inc/amutils.js.gz if this file is present). Do not prefix the extension with a period.  Note that regardless of the extension, Content-Encoding: gzip header will be sent.
    WARNING: Currently all preauth and postauth filters will be skipped if we find a .gz file and return it regardless of the skipfilters setting.

  4. Compression mode for on-the-fly compression which is done if .gz file was not found or the extension was not set for this url. Currently only supports "gzip" and "none".  If blank, global default is used as set based on the server-level gzip parameter described earlier.  Note that the compression mode specified here can be overridden by your own preauth or postauth filter or registered procedure/adp itself with am_conn_compress 1|0.  Again, on-the-fly compression for fastpath will only happen with our 4.5.2 version and fastpath direct parameter set to false.

Caveats

Skipfilter and compression handling is implemented by this module with C filters.  However, filter url pattern matching is not the same as the trie-based url matching used by registered procedures and by pools and limits.  Therefore, it is possible to configure multiple pools whose registered url patterns overlap. Which pool of threads will actually be used is determined by normal AOLserver url-walking mechanism.  However, the skipfilter and compression handling behavior when these settings differ between the two pools is unpredictable. So, be sure to carefully divide the URL space between the pools.

Here is an example of such a conflicting configuration for url /mydir/subdir/mydoc.doc:

ns_section "ns/server/$server/pool/pool1"
ns_param map {GET /*.doc "gz" ""}

ns_section "ns/server/$server/pool/pool2"
ns_param map {GET /mydir "" "gzip"}

ns_section "ns/server/$server/pool/pool3"
ns_param map {GET /mydir/subdir "" "none"}

Although this url will be processed by pool1, its compression settings depend on the sequence in which pools are defined and is difficult to predict, especially if skipfilters is also set for preauth.

Finally, such a conflict is possible not only between pool configurations but also within a single pool configuration between different maps.

Note that content returned using ns_write or ns_returnfp or content that is streamed will not be compressed.

Tcl API Syntax

You generally do not need to manually use these APIs but here is the documentation for reference:

am_registerGzFileFilter when method pattern ?extension? ?mode?

ns_register_filter_error  ?-first? when method pattern

am_conn_compress 1|0

Description

am_registerGzFileFilter takes the following mandatory arguments, the first three the same as in ns_register_filter:

  • when must be one of {prequeue, preauth, postauth or trace} indicating at which stage of connection processing the filter should fire.  It is recommended preauth is used.
  • method is an HTTP method such as GET, POST or PUT
  • pattern is a glob-style pattern expression that describes a set of URLs for which the filter is registered.

 The optional arguments are:

  • extension (e.g. "gz" without a period) of a pre-compressed file in the same directory to serve instead if present.
  • compression mode e.g. "gzip" or "none".

This command registers a C filter that, when fired, appends the specified extension (after a period) to the requested url and if the file exists, then it will be returned instead.  Otherwise, if the file was not found or the extension was not specified, the compression flag for the current connection is set according to the specified mode. (Do nothing if blank, "none" to disable compression and enable otherwise).

If both extension and mode are blank no filter gets registered (no error either).

To be clear, currently this filter will NOT create a .gz file on the fly if one does not exist.

Note that the filter is always registered at the top of the filters list for the specified method, pattern and when and therefore this command requires the patch that adds the -first switch to ns_register_filter (which we include in 4.5.2) (RFE 1012103).

ns_register_filter_error registers a filter that simply returns NS_ERROR. It could be registered in a regular way or at the top of the list if -first option is specified. The rest of the arguments are identical to those of ns_register_filter.  The reason for this facility is if a trace filter returns an error, then void_traces and nslog access logging are skipped.

am_conn_compress enables/disables compression for the current connection by specifying 1 or 0 respectively.  You might use am_conn_compress 0 (which we also wrap in tcl in am_conn compress 0) to disable compression if you are returning a .zip file for example.

 

URL Aliases | amattributes2set | ampools | ADP Master Pages
 

© Copyright 1996-2014 by am.net and Solitex Networks. Legal Notices.
Creative Commons License Articles on this site are licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.