Basic Caching

Based on a post by Dave Bauer.

OpenACS docs are written by the named authors, and may be edited by OpenACS documentation staff.

Caching using the database API is described in the database API tutorial.

Caching using util_memoize

  1. Implement your proc as my_proc_not_cached

  2. Create a version of your proc called my_proc which wraps the non-cached version in the caching mechanism. In this example, my_proc_not_cached takes one argument, -foo, so the wrapper passes that on. The wrapper also uses the list command, to ensure that the arguments get passed correctly and to prevent commands passed in as arguments from being executed.

    ad_proc my_proc {-foo} {
            Get a cached version of my_proc.
    } {
        return [util_memoize [list my_proc_not_cached -foo $foo]]
  3. In your code, always call my_proc. There will be a separate cache item for each unique call to my_proc_not_cached so that calls with different arguments are cached separately. You can flush the cache for each cache key by calling util_memoize_flush my_proc_not_cached args.

  4. The cached material will of course become obsolete over time. There are two ways to handle this.

    • Timed Expiration: pass in max_age to util_memoize. If the content is older than max_age, it will be re-generated.

    • Direct Flushing. In any proc which invalidates the cached content, call util_memoize_flush my_proc_not_cached args.

  5. If you are correctly flushing the cached value, then it will need to be reloaded. You may wish to pre-load it, so that the loading delay does not impact users. If you have a sequence of pages, you could call the cached proc in advance, to increase the chances that it's loaded and current when the user reaches it. Or, you can call (and discard) it immediately after flushing it.