Distributing Configuration Values
The proposed system contains a very simple caching methodology to enable values retrieved from the centralized database to be stored locally on the client servers for later retrieval. To make the process simple and flexible, the simple class framework illustrated in Figure 2
helps local clients read configuration values from the centralized database, store them in a local cache (the Windows Registry), and keep the values updated appropriately.
|Figure 2. Property Class Framework: This extensible class framework manages both remotely and locally cached property values.|
This configuration caching strategy provides another important advantage. In the event that the central storage system is unavailable at the time of application startup, when many application configuration values are traditionally retrieved, the application will either not be able to start or will be left in a precarious state. Using a persistent local cache results in higher availability.
|Figure 3. Property Value Flowchart: This flowchart depicts the nominal flow that results when a client reads a property value.|
At the heart of the framework is a PropertyValue class that client applications use to read property values. The clients can remain unaware that configuration information is managed remotely and cached locally. Under the covers, the PropertyValue class first checks the local cache for the requested property value. If the value is found locally, it quickly returns the value to the client; otherwise, the class retrieves the value from the central database, stores it locally, and then returns the value to the client. Figure 3
shows the high-level flow used by the PropertyValue class.
The PropertyValue class has a Lifetime
property that determines whether cached values have expired. Expiration, in this case, simply means the value should be re-retrieved from the central database. This aging process forces periodic updates to the local copies of property values across all the machines in the enterprise. The escPropertyValues
field contains the number of seconds before a local property value must be refreshed. When a client requests an expired value, the class refreshes the value from the central database and updates the local value before returning the value to the client.
To cover situations when the central database is unreachable, the class behaves as follows:
- When a property value has not yet been stored locally, the PropertyValue class returns a null value.
- When a property has been stored locally, but has expired, the PropertyValue class returns the locally-stored value.
This scheme serves both to keep data as current as possible, and makes it highly likely that a requested property value will be found locally in the unlikely event of an unreachable central database server.
Many readers may protest that the solution proposed here implements the central repository using SQL Server. Even more may protest using the Windows Registry as the local repository of cached property values. I could argue that these are probably the best all-purpose choices for these storage choices. However, the class framework displayed in Figure 2 supports pluggable interchangeability of both the local and remote storage mechanisms. In most cases, I would argue that SQL Server or another enterprise-class relational database is usually the best choice for the central repository for property values. However, in cases where a server hosts mostly web applications, it may make more sense to employ the ASP.NET cache for local storage.
The extensibility mechanisms built into both the LocalStorageClient and the RemoteStorageClient work nearly identically. You can quickly extend the framework to support other local and remote storage mechanisms. For example, suppose you want to store local configuration properties in an XML file. Here's the procedure.
First, create a new class that inherits from LocalStorageClient, and implement the two mustoverride methods: LocalPropertyValue_Get and LocalPropertyValue_Set. These two methods read and write PropertyValue objects locally. To use an XML file for storage, you will need to write code to support opening and closing the XML file, reading and writing to the XML file, and so forth. The BuildPropertyValue method of the LocalStorageClient base class aids in building a PropertyValue class from the values retrieved from the XML file.
Note that there's no reference to the mechanism used by the RemoteStorageClient. Nor is there any code used to check whether the locally stored value has expired. That's because the PropertyValue class handles those tasks. If a property value must be updated from remote storage, the PropertyValue class coordinates the interaction between the RemoteStorageClient and LocalStorageClient as shown in Figure 3.