Click here to Skip to main content
Click here to Skip to main content

Practical .NET Remoting Caching Sink

, 27 Jun 2003
Rate this:
Please Sign up or sign in to vote.
A cache mechanism for .NET Remoting

Introduction

.NET Remoting solutions can be slow because of unnecessary "chatty" calls. For programmers, making a method call is easier than creating sockets, preparing buffers, calling send() and recv(), and then parsing the result. So much easier that he often forgets about performance. Another reason is that when we want to use PropertyGrid to present a remoted (MBR) object: A lot of property get/set methods are called, some of them are unnecessary, but we can't help because we can't modify code inside PropertyGrid, yet we want to use this powerful control.

By using this caching sink, the task of optimizing performance of Remoting projects can be greatly simplified to just placing some attributes. The caching sink works on the client side by returning previous result if the server indicated the client can do so. Methods can have "caching attributes", indicating how long clients can cache the result.

How to use

Configuration Files

Here is the remoting config file that shows where to insert these sinks.

<serverProviders>
  <formatter ref="binary" />
  <!-- Sets X-Cache from CacheTime attribute of the method -->
  <provider type=
    "System.Runtime.Remoting.Caching.CachingServerSinkProvider, RemotingCache" />
</serverProviders>
<clientProviders>
  <formatter ref="binary" />
  <!-- return cached results if applicable -->      
  <provider type=
    "System.Runtime.Remoting.Caching.CachingClientSinkProvider, RemotingCache" />
</clientProviders>

Of course, you need to compile the source code and make RemotingCache.dll.

Caching Attributes

using System.Runtime.Remoting.Caching;
//CacheTime
[CacheTime("00:01:00")] 
public override string ToString() {
  return "some string that won't change for one minute";
}
public string Name { 
[CacheTime("01:00:00")] 
get{
    return "some property that won't change for one hour";
  }
} 

//InfinitelyCached
public string Name { 
[InfinitelyCached] 
get{
   return "some property that won't change forever";
  }
}

How it works

The sink on the server side is easy: it simply reads the caching attributes on the method being called and return the information in form of "X-Cache" entry in the response header. the string in this entry will be passed to TimeSpan.Parse() on the client side (so the format("hh:mm:ss") should be used in the CacheTime attribute).

The most difficult part in implementing this caching mechanism is on the client side. It is the part of designing a hash-key scheme so that only the exact same call matches the entry, where the previous result is stored. I'll briefly explain the design taken in this work. The hash-key has two part:

  1. The object Uri, typename and the method name.
  2. The request stream.( Note because the sink is placed after formatter, all information in IMessage is contained in Request stream, so IMessage can totally be ignored )

When the two hash keys are compared, the first part is compared first. So when the call is on a different object, or it has a different method name, the comparison will end without comparing the whole data in request (e.g. parameters).

For hash-key generation, there are other approaches that use BinaryFormatter to serialize the request IMessage, and store the serialized "opaque" data as key. This proves not only to be time consuming (thus defying the purpose of performance improvement by caching), but also extremely unstable -- The binary formatter seems to be unable to serialize IMessage: it throws ExecutionEngineException which is un-catchable and brings the whole execution environment down.

By placing the sink AFTER formatter in the client sink provider chain, My solution does not need to do serialization to calculate the key.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

zhi
Researcher
United States United States
My name is Zhiheng Cao. I major in Eletronics Engineering, in University of Tokyo. I do part time jobs of computer programming and teaching high school students English and Mathematics.
 
CodeProject provided me with valuable information for my programming job many times in the past. I hope I can do my part by providing goodies I have.
 

Comments and Discussions

 
GeneralForce update of the cache PinmemberLars Roith29-Mar-04 21:37 
Hello,
 
I think the solution provided is missing one big feature.
If I understand correctly the only way to get a new value is to wait until the cache time elapses.
It would be very nice to be able to force an update of the cache.
 
If we are not able to force an update we cannot use properties correctly because (as I understand) we use the methodinfo to build the key for the cache. So get is different from set and when set is called the value associated with get will not be updated (or am I wrong?).
 
Nevertheless, quite a good piece of code (except the layout and documentation) and very useful in many scenarios.
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411022.1 | Last Updated 28 Jun 2003
Article Copyright 2003 by zhi
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid