12.4 Caching
To illustrate caching, I
extend the server object used in the previous sections. I add three
accessor methods to access the three server instance variables:
public boolean getBoolean( );
public int getNumber( );
public String getString ( );
Now you can add a generic server-object proxy implementation that
handles caching. The implementation is essentially the same for all
three communications layers:
package tuning.distrib.custom;
public class ServerObjectCacher
implements ServerObject
{
ServerObject stub;
boolean b;
boolean bInit;
int i;
boolean iInit;
String s;
boolean sInit;
public ServerObjectCacher(ServerObject stub)
{
super ( );
this.stub = stub;
}
public boolean getBoolean( )
{
if (bInit)
return b;
else
{
b = stub.getBoolean( );
bInit = true;
return b;
}
}
public int getNumber( )
{
if (iInit)
return i;
else
{
i = stub.getNumber( );
iInit = true;
return i;
}
}
public String getString ( )
{
if (sInit)
return s;
else
{
s = stub.getString( );
sInit = true;
return s;
}
}
public void setBoolean(boolean flag)
{
bInit = false;
stub.setBoolean(flag);
}
public void setNumber (int i)
{
iInit = false;
stub.setNumber(i);
}
public void setString(String obj)
{
sInit = false;
stub.setString(obj);
}
public void setAll(boolean flag, int i, String obj)
{
bInit = iInit = sInit = false;
stub.setAll(flag, i, obj);
}
}
As you can see, this is a simple proxy object. Each accessor is
lazily initialized,
and calling any updating method resets the accessors so that they
need to be reinitialized from the server. This ensures that any logic
executed on the server is not bypassed. If the server object can be
changed by other client programs, you need to add callback support
for this caching proxy so that whenever the server object is changed,
the client proxy is reset.
Running access tests using this caching proxy is simple. The client
code needs to be changed in only one place; once the server object is
resolved, the resolved proxy is wrapped in this caching proxy. Then
it is used exactly as previously:
ServerObject obj = (ServerObject) Naming.lookup("/ServerObj");
//now wrap the server object with the caching proxy
obj = new ServerObjectCacher(obj);
//All the rest of the code is the same
The timing results are dependent on how many iterations you test of
the uncached versus cached access. After the first access, the cached
proxy access is a simple local-variable access, whereas the uncached
access requires remote messaging. The difference in timings between
these two access mechanisms is more than a factor of 1000, so the
more iterations of the tests you make, the bigger the overall
relative difference in timings you measure. For example, with
accesses repeated 500 times, the average cached access takes about
0.5% of the average uncached access time. Doubling the number of
repeated accesses to 1000 times doubles the time taken for the
uncached access, but the cached access time is essentially the same,
so the time is now 0.25% of the average uncached access
time.
|