SolutionsTools & SDKSupport  



Quick Links
 
Techniques for Managing the Openwave Mobile Browser Cache
 
 
Introduction

This technical note presents a sample "to-do" list application written in WML1.1 and Perl. The application source code demonstrates various techniques for managing the Openwave Mobile Browser cache.

NOTE:  The example code included with this technical note uses the Perl application utilities from the Openwave SDK 4.1.

How the Mobile Browser Cache Works

The Openwave Mobile Browser caching model is similar to the HTML web browser caching model. The biggest difference is that with the Openwave Mobile Browser, more responsibility is placed on the application developer to keep the cache in sync with the server. In traditional wired networks, the cost of asking the web server if an HTML page has changed since it was last downloaded is usually far less than the cost of reloading the page. This is not the case in wireless networks, where it may take several seconds just to establish a server connection. For this reason, the Openwave Mobile Browser does not do the if-modified-since negotiation. The Openwave Mobile Browser provides other means by which a developer can maintain cache coherency.

Why Should You Care?

The main goal of the cache is to reduce round trips to the server. This is important not only because of the high latency of wireless networks, but also because the user may incur a cost for every request. Making efficient use of the cache will not only make the application faster, but it could also save the user money!

The trick in dealing with the cache is that you want to store decks in the cache for as long as possible, but you never want to show the user stale data. For example, a real-time stock quote service would probably not want to cache a deck containing volatile quote information. Another example is managing a list of data (e.g. a to-do list). You want list decks to be cached for as long as possible. However, when you delete or add an item to the list, you no longer want to navigate to an out-of-date list.

For more information on managing the Openwave Mobile Browser cache, please refer to Chapter 2 of the UP.SDK Developer's Guide.

Source Code

The sample source code implements four different versions of a to-do list application. Each version builds upon the previous version and implements a better approach to managing the cache:

todoData.pm Application utility functions
todo1.cgi Uses default caching behavior
todo2.cgi Sets Cache-Control for the deck
todo3.cgi Sets the cache ID in the deck's digest entry
todo4.cgi Returns a cache operation in the digest

NOTE: Each example CGI script is written in Perl, and depends on the sample Perl utility libraries installed with the Openwave SDK in the examples/apputils subdirectory.

todoData.pm

    This application utility package defines common functions used by each of the todo*.cgi scripts. Put this file in the same directory as each of the todo*.cgi scripts.

    IMPORTANT: Change the $dataDir variable in this file to point to the path of the data directory on your web server. The directory must be writable by the web server process. This is the directory where the to-do list data files will be stored (per subscriber).

todo1.cgi

    In this first version of the to-do list application, note that there is no "Cache-Control" set for the to-do list deck. This is desirable since the user may want to view the to-do list several times throughout the day. However, it is not sufficient to omit the "Cache-Control" and expect correct caching behavior. When the user first navigates to the to-do list, they will request a URL similar to:
      http://www.myserver.com/todo/todo1.cgi
    When the user modifies an entry in the to-do list, they will invoke a new URL similar to:
      http://www.myserver.com/todo/todo1.cgi?NS=SETSTATUS&sts=P&index=1
    There will now be two list decks in the browser's cache. Since we ignore the "Cache-Control" in this version of the to-do list, both of these decks are valid in the cache. If the user re-navigates to the main URL (todo1.cgi), they will see the older list data, since the Openwave Mobile Browser will get a cache hit on the first URL and not reload it from the server.

    To solve the problem, we need a way to instruct the Openwave Mobile Browser to reload the deck whenever it is navigated to...

todo2.cgi

    This version is the same as the previous version, with the exception that the meta tag of Cache-Control=must-revalidate has been set for the deck. The Openwave Mobile Browser will reload the deck from the server every time the user navigates to it, because its Cache-Control in the cache is set to "must-revalidate". Along with the main to-do list, we also need to set a Cache-Control on the Finished Items list so that it will also be kept in sync with the server data.

    While this solves the problem of cache consistency, it does so in a very brute force manner and does not make efficient use of the cache. Another important thing to remember about Cache-Control is that the browser will ignore a deck's Cache-Control value if a TASK=PREV is used to navigate to the deck (typically from the user pressing the Back key). This is particularly important to keep in mind when using Cache-Control. It means that a Cache-Control=must-revalidate deck can generate a cache hit. Cache-Control is also ignored if you navigate to a card in the same deck.

    To solve the problem, we need a way to alter the cache ID of the to-do list deck that gets returned after we modify an entry...

todo3.cgi

    By default, the Openwave Mobile Browser identifies a deck in the cache via the URL used to download it. There are cases when it is useful to override a deck's cache ID. For example, it is necessary to do so when returning multiple decks in a single digest. Otherwise, all of the decks in the digest will have the same cache ID and will overwrite each other. Another reason to override a deck's cache ID is to "alias" it to another deck in the cache (explicitly overwrite another entry).

    By removing Cache-Control=must-revalidate and adding a cache ID to the addDeck function, we now get good cache behavior. The addDeck call now looks like this:

      $digest->addHDMLDeck("?", sprintf($TODOLIST));
    Note the use or "?" as the first parameter. The first parameter is a relative URL that will become the deck's cache ID. By setting this to "?" the cache ID will be the same as the requesting URL, only without the query arguments. So, when the user modifies a to-do list entry, a URL like this will get requested:
      http://www.myserver.com/todo/todo1.cgi?NS=SETSTATUS&sts=P&index=1
    This resulting deck will get added to the digest and because of the "?" it will get added with a cache ID of
      http://www.myserver.com/todo/todo1.cgi
    This is exactly what we want since this is the same URL that is used to view the to-do list. This solves the problem for the main to-do list but not for the Finished Items list. If we remove the Cache-Control=must-revalidate from that list, we still have a cache coherency problem. To make the Finished Items list have good caching behavior we need to use a cache operation...

todo4.cgi

    With a slight modification to the SetStatus function, we can achieve good caching behavior of the Finished Items list. Ideally, we want the Finished Items list to be cached as long as possible, but have it reloaded if new items get marked as finished. To do this, we add a cache operation to the SetStatus function. If an entry gets set to Finished (a status of F), we invalidate the Finished Items deck in the cache as follows:
      $digest->addCacheOp($Digest::InvalURL, "?NS=FINISHED");
    The cache operation tells the browser to invalidate the cache entry specified by the given relative URL. This is added to the response digest. Now, the next time the user goes to the Finished Items list, it will get reloaded from the server. Before we're done, we need to add the same cache operation to the EraseFinishedItems function. This invalidates the Finished Items deck whenever the user erases an item from the list.
 
Copyright © 2000-2008 Openwave Systems Inc.    Openwave  |  Terms & Conditions  |  Privacy Policy