docs.roxen.comBack to normal mode
DocsRoxenWebServer 3.3System Developer ManualImportant Concepts
Copyright © 2004, Roxen Internet Software
Suggestions, comments & compliments
manuals@roxen.com

RXML Cache Considerations

As you probably know, the RXML parse tree is often cached. The <cache> tag also caches the result of the RXML evaluation, save (normally) for nested <cache> tags. When the <cache> tag caches the result, it also caches any variable changes made with RXML.set_var, RXML.Context.set_var etc.

Changes directly in id->misc and RXML_CONTEXT->misc (aka id->misc->defines) is however not known by the cache system and therefore not saved. This can be a problem when tags uses either of those two mappings to pass state between each other. A (rather silly) example to illustrate:


<my-set value="foo"/>    <!-- Does id->misc->my_value = "foo" -->
  ...
<my-get/>                <!-- Returns id->misc->my_value -->

Now, if <my-set> is surrounded by a <cache> tag, there's a problem:


<cache>
 <my-set value="foo"/>    <!-- Does id->misc->my_value = "foo" -->
</cache>
  ...
<my-get/>                 <!-- Returns id->misc->my_value -->

When the <cache> tag is evaluated the second time, it won't redo the assignment id->misc->my_value = "foo", since it doesn't know it has happened. Therefore <my-get/> will not return the same thing.

There are three ways to solve this:

  • Add the flag RXML.DONT_CACHE_RESULT to the flag field for the involved tag, i.e. <my-set> in this example. The <cache> tag will never cache the result of <my-set> then, so it will be properly reevaluated each time. Otoh, this also defeats the purpose of the cache.

  • Use RXML.set_var and similar functions to set values instead, e.g:


    <cache>
     <my-set value="foo"/>   <!-- Does set_var("my_value", "foo", "var") -->
    </cache>
      ...
    <my-get/>                <!-- Returns get_var("my_value", "var") -->
    

    The set_var call is intercepted by the cache, so it will be redone when the cached value is reused. The downside of this approach is that the variable will be user accessible (with in this example).

  • Use RXML_CONTEXT->set_misc to set the values, e.g:


    <cache>
     <my-set value="foo"/>   <!-- Does RXML_CONTEXT->set_misc("my_value", "foo") -->
    </cache>
      ...
    <my-get/>                <!-- Returns RXML_CONTEXT->misc->my_value -->
    

    This is very similar to the second approach above, except that the variable won't be user accessible. The function set_misc simply sets a value in RXML_CONTEXT->misc but also records the setting for the cache.

    This is a potential problem with old tags when used together with <cache> (although it didn't work any better before).

Note!

The first alternative, i.e. to add RXML.FLAG_DONT_CACHE_RESULT, should not be used internally. It's considered better that it simply breaks (as it always has done as long as the <cache> tag has been around) than that the cache is disabled.