Adobe® LiveCycle® Data Services ES 2.6 Developer Guide

Caching data locally and offline

You can write a Flex client application that caches client data requests and data changes to the local file system. This lets an application store the contents of executed fill(), getItem(), and count() operations for later retrieval when an application resumes in online mode. The offline mode lets you create an application that can work when the host is shut down, a network connection is unavailable, or the host is restarted with the application loaded.

The DataService.cacheID property is a string that provides an identifier for locally stored data. If two Flex applications use different values for the cacheID property, they use independent cached stores of data. If they use the same value for the cacheID property, they share the same store of data. In general, you should not run two Flex applications at the same time using the same cacheID. A value of null or empty string is considered unset. If you do not set the cacheID property, all cache methods and properties are considered inconsistent and throw errors accordingly. The value of the cacheID property can be changed during the course of an application's operation. When changed, the current state of the data is flushed to local storage. All currently loaded data remains in memory, letting you selectively add or remove cached data on disk using the new identifier. This results in copy-on-write behavior if you set the DataService.autoSaveCache property to true. A corresponding method called getCacheIDs() retrieves all cacheID values used for a single application. When two or more applications run under the same domain and use the desktop Flash Player to execute with the same cacheID, changes are reflected in all running instances as if they were the same application. This mechanism bypasses conflict detection between the running instances; there can be no conflicts between applications for any changes made locally.

You use the DataService.autoSaveCache property to indicate when data should be saved locally. The default value of this property is false. Set this property to true when you want the data managed by the DataService instance to be saved to the local file system after any change, including creates, reads, updates, deletes, page requests, and lazy loading (for information about lazy loading, see The managed association approach). When you set the autoSaveCache property to false, you must manually save data to the local file system. You do that with a corresponding method called DataService.saveCache(). The saveCache()method gives you control over the timing of save operations. You use it to force a save of the current state of the cache to local storage. You can specify an optional parameter to provide further granularity over what is stored locally. Another method, DataService.clearCache(), lets you remove all locally stored data associated with the DataService instance. The clearCache() method also takes an optional parameter to indicate a specific piece of data that should be removed from the local file cache. For more information on the saveCache() and clearCache() methods, see Saving and clearing cached data.

Another important property for working with locally cached data is the DataService.autoConnect property. This property lets you change the current default behavior that attempts to connect a DataService instance to the remote destination when in a disconnected state during each operation. When the autoConnect property is set to false, operations that require a connection when the DataService is disconnected do not fault unless there is problem loading data from the cache.

The DataService.connect() method corresponds to the autoConnect property. The connect() method lets you control the timing of a reconnect attempt when the autoConnect property is set to false. The DataService instance always attempts to load any local data before attempting to establish a connection and satisfy a fill() or getItem() request. Setting the autoConnect property to false prevents any attempts to connect with the remote destination. Changing the value from false to true is equivalent to calling the connect() method. This behavior lets you use data binding to establish the connectivity of an application using a user interface component such as a CheckBox.

If there is a connection available after the local cache is loaded, the current reconnectPolicy property value is consulted to determine how a request for the current data will be made. If the reconnectPolicy property is set to IDENTITY, no request for remote data is made because it is assumed that the data is up-to-date. If the reconnectPolicy property is set to INSTANCE, a request for the remote data is made and the result of that fill is used to overwrite the current in-memory version. In this situation, if the autoSaveCache property is set to true when the new data is returned, it is saved to local storage overwriting the previous version.

The ActionScript code snippet in the following example uses the cacheID, autoSaveCache, and autoConnect properties:

...
var usersOfD:DataService = new DataService("D");
// unique id for this session.
usersOfD.cacheID = "SN108ADFGEER091878-F";
// Save the cache automatically when online.
usersOfD.autoSaveCache =!workOffline;
// If working offline don't attempt to connect.
usersOfD.autoConnect = !workOffline;
usersOfD.fill(users, "notorious");
...

For paged and lazily loaded data, each time a request is satisfied, those results are stored locally when the autoSaveCache property is set to true. To make all of the data available offline for a paged result set, call the seek() cursor method, specifying a prefetch of the entire length.

The items in a request are identified by the request parameters. In this code sample, the key for the list of items returned in the fill is notorious. When the application is reloaded in a disconnected state, it uses the client database API to request the data from the local store that uses the SWF URL and destination name, and requests the items with the key value of "notorious".

Note: Run-time configuration information is saved to the local cache when present during a save, and is restored during initialization if a connection cannot be established. For more information about run-time configuration, see Run-time configuration.

The standard Data Management Service conflict resolution model is used when data is cached offline. When a client tries to commit stale data from changes made offline, the assembler can use the old and new versions of the object to report a conflict.

About caching with Flash Player and AIR

Flash Player and AIR each cache data to the local file system by using a different mechanism. Flash Player uses local shared objects (LSOs), while AIR uses a SQL database.

When using Flash Player, it creates a .sol file to store the LSO. Flash Player creates a new directory for the application and domain based on your platform and operating system. For example, for a Flash Player application on Microsoft Windows 95/98/ME/2000/XP, the .sol files are created in the following directory:

c:/Documents and Settings/userName/userDomain/Application Data/Macromedia/Flash Player/#SharedObjects/webDomain/pathToApplication/applicationName/lsoName.sol

Note: There are performance and scalability limitations when using local shared objects to cache data offline. There is a configurable user limit, with a default size of 100 kilobytes. Writes are monolithic, so each save writes all managed data for that data store.

When using AIR, SQL database files are created in the _ds_localcache sub directory of the application storage directory. The location of the application storage directory is defined by the setting of the air.File.applicationStorage property. For example, for an AIR application named TestApp running on Windows 95/98/ME/2000/XP, SQL database files are created in the following directory:

C:\Documents and Settings\userName\Application Data\TestApp\Local Store\_ds_localcache

Each cacheID, specified by the DataService API, corresponds to a single database file.

When you compile your application, you must link in the appropriate SWC file to control caching, depending on whether you are deploying your application on Flash Player or AIR, as follows:

  • playerfds.swc Link this SWC file for applications running in Flash Player.
  • airfds.swc Link this SWC file for applications running in AIR.

Saving and clearing cached data

You use the DataService saveCache() and clearCache() methods to manually control what specific data is stored in the cache or removed from the cache. The saveCache() and clearCache() methods take an argument of type Object, which is null by default. If you specify this argument, it must be a collection or a single managed object (SMO) that is already under management by the Data Management Service.

The following example shows how to use the DataService saveCache() and clearCache() methods in an ActionScript script block:

<mx:Application creationComplete="loadData()"> 
    <mx:DataService id="usersOfD" destination="D" />
    <mx:DataGrid id="usersGrid" dataProvider="{users}">
    </mx:DataGrid>
    <mx:Button label="Save"
        click="usersOfD.saveCache(ArrayCollection(usersGrid.dataProvider))"/>
    <mx:Button label="Clear"
        click="usersOfD.clearCache(ArrayCollection(usersGrid.dataProvider))" />
    <mx:Script>
        <![CDATA[
            [Bindable]
            private var users:ArrayCollection;

            private function loadData(){
                usersOfD.fill(users);
            }
        ]]>
    /mx:Script>
</mx:Application>

In the preceding example, the users are loaded when the application is initialized by calling the fill() method of the usersOfD service. When a user clicks the Save button, the saveCache() method is called to pass in the users ArrayCollection, which saves only the items of this collection to the local store. When a user clicks the Clear button, the clearCache() method is called to pass in the same users ArrayCollection, which then clears only the items of this collection from the local store. Since this collection was the only data stored locally, no files should be found on the local system.

Inspecting the data cache

You use the mx.data.CacheDataDescriptor class to inspect the various attributes of offline cached data. This class contains the following properties: lastAccessed:Time, lastWrite:Time, creation:Time, metadata:Object, and id:Object.

The DataService class contains the following related methods: getCacheDescriptors(), getCacheData(), and clearCacheData(). The getCacheDescriptors() method returns an ICollectionView of CacheDataDescriptor(s) describing the attributes for all of the cached data. If a managed ArrayCollection or a managed item is specified, the collection returned contains only a single CacheDataDescriptor specific to the specified argument. The getCacheData() method returns the collection or item data based on the specified cache descriptor. The returned value is pulled directly from the local cache and is not managed. Additionally, a new instance of the collection or object is returned on each call. Calling the clearCacheData() method removes the associated data from the local store for the descriptor specified.

The following example shows an application that uses this API. In this example, all of the cached collection and item information is returned for the usersOfD service. The metadata property is set as a string that contains a descriptive name for the cached data. The grid displays the descriptive name along with the last accessed, creation, and last updated times.

<mx:Application creationComplete="displayCacheInfo()"> 
    <mx:DataService id="usersOfD" destination="D" />
    <mx:DataGrid id="cachedDataInfo" dataProvider="{cacheInfo}"
        change="updateDisplay()">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="metadata" />
            <mx:DataGridColumn headerText="Last Accessed"
                dataField="lastAccessed"/>
            <mx:DataGridColumn headerText="Created" dataField="created" />
            <mx:DataGridColumn headerText="Last Updated" dataField="lastWrite"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:DataGrid id="dataDisplay" dataProvider="{cacheData}"/>
    <mx:ArrayCollection id="cacheData"/>
    <mx:Script>
        <![CDATA[
            [Bindable]
            private var cacheInfo:ArrayCollection;
            private function displayCacheInfo(){
                usersOfD.getCacheDescriptors(cacheInfo, CacheDataDescriptor.FILL);
            }
            private function updateDisplay():void{
                var token:AsyncToken =
                    usersOfD.getCacheData(cachedData.selectedItem);
                token.addResponder(new AsyncResponder(
                    function (event:ResultEvent, o:Object):void{
                        cacheData = ArrayCollection(event.token.result);
                    },
                    function (event:FaultEvent, o:Object):void{
                        Alert.show("Could not load cache data");
                    }));
            }
        ]]>
    </mx:Script>
</mx:Application>

The following example shows an application in which all of the cached collection and item information is returned for the usersOfD service. The metadata property is set to a string that contains a descriptive name for the cached data. The DataGrid displays the descriptive name along with the last accessed, creation, and last updated times. When the user selects an item and presses the Remove button, the selected item (CacheDataDescriptor) is used first to access the existing data from the cache if it is not already loaded, and then to pass that item to the clearCacheData() method, which removes it from the local cache.

<mx:Application creationComplete="displayCacheInfo()"> 
    <mx:DataService id="usersOfD" destination="D" />
    <mx:DataGrid id="cachedData" dataProvider="{cacheInfo}">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="metadata" />
            <mx:DataGridColumn headerText="Last Accessed"
                dataField="lastAccessed"/>
            <mx:DataGridColumn headerText="Created" dataField="created"/>
            <mx:DataGridColumn headerText="Last Updated" dataField="lastWrite"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:Button label="Remove"
        click="removeFromCache(cachedData.selectedItem)"/>
    <mx:Script>
        <![CDATA[
            [Bindable]     
            private var cacheInfo:ArrayCollection;
            private function displayCacheInfo(){
                usersOfD.getCacheDescriptors(cacheInfo);
            }
            private function
                removeFromCache(descriptor:CacheDataDescriptor):void{
                var token:AsyncToken = usersOfD.getCacheData(descriptor);
                token.responder = new AsyncResponer(
                function (result:ResultEvent, o:Object):void{
                    usersOfD.clearCacheData(descriptor);
                },
                function (fault:FaultEvent, o:Object):void{
                    Alert.show("Failed to get specified cache data");
                }));
            }
        ]]>
    </mx:Script>
</mx:Application>


 

Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/livecycle/8.2/programLC/programmer/lcds/dms_advanced_2.html