You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@river.apache.org by Christopher Dolan <ch...@avid.com> on 2011/04/04 17:31:26 UTC
Code example: registrar Locator caching
Here's an idea that I use in my River client code that may be useful for
others. This code is not appropriate for inclusion in River, but is
more a "cookbook" idea.
I have many DiscoveryListener instances in my code, which respond to
discovered() and discarded() messages for registrars joining and leaving
the djinn. I like to log which registrar is leaving in the discarded()
method, but the getLocator() method is remote and I can't invoke it on a
discarded registrar, obviously. So, I memoize the getLocator() and
getGroups() methods for my registrars (I know for fact that my
registrars never change groups or locators in their lifetimes).
To accomplish this, I created a ProxyPreparer implementation that wraps
an existing ProxyPreparer (usually BasicProxyPreparer, but not always)
and adds an additional invocation step. The important parts of the code
are like the following. I've omitted the constructor that creates
m_innerProxy from the wrapped ProxyPreparer and I've also omitted some
boilerplate code that unwraps thrown InvocationTargetException and
UndeclaredThrowableException instances.
private static final Method s_getLocatorMethod;
private static final Method s_getGroupsMethod;
static {
Method getLocatorMethod = null;
try {
getLocatorMethod =
ServiceRegistrar.class.getMethod("getLocator");
} catch (Throwable e) {
// leave null
}
s_getLocatorMethod = getLocatorMethod;
Method getGroupsMethod = null;
try {
getGroupsMethod =
ServiceRegistrar.class.getMethod("getGroups");
} catch (Throwable e) {
// leave null
}
s_getGroupsMethod = getGroupsMethod;
}
private Object m_cachedLocator = null;
private final Object m_cachedLocatorLock = new Object();
private Object m_cachedGroups = null;
private final Object m_cachedGroupsLock = new Object();
/* (non-Javadoc)
* @see
java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[]
args) throws Throwable {
if (s_getLocatorMethod.equals(method)) {
synchronized (m_cachedLocatorLock) {
if (m_cachedLocator == null)
m_cachedLocator =
method.invoke(m_innerProxy, method, args);
return m_cachedLocator;
}
} else if (s_getGroupsMethod.equals(method)) {
synchronized (m_cachedGroupsLock) {
if (m_cachedGroups == null)
m_cachedGroups = method.invoke(m_innerProxy,
method, args);
return m_cachedGroups;
}
} else {
return method.invoke(proxy, method, args);
}
}
Chris Dolan
Principal Software Engineer | P&S Integrated Media Enterprise
Avid
6400 Enterprise Ln, Madison WI 53719
United States
christopher.dolan@avid.com <ma...@avid.com>
t 608-288-5104
We're Avid. Learn more at www.avid.com <http://www.avid.com>
Re: Code example: registrar Locator caching
Posted by Gregg Wonderly <ge...@cox.net>.
This is one of the things that I do on a regular bases. But in various ways.
Sometimes, I create a MAP that goes from serviceID to some object that holds all
this stuff, including the reference to the prepared proxy and any other data
that needs to stay live. At discovery, I call getLocator() and anything else
that would need to be used over the lifetime of the visibility to me, and then
store that information inside of the container object.
There might be something that we can do with some changes to the discovery APIs
to introduce such a container object that would allow "Properties" of the
registrar to be preserved/cached in particular ways.
If anyone else has some other things or ways that they've done this, it would be
interesting to hear about those to see if there is a theme that would be worth
representing in an API.
Gregg Wonderly
On 4/4/2011 10:31 AM, Christopher Dolan wrote:
> Here's an idea that I use in my River client code that may be useful for
> others. This code is not appropriate for inclusion in River, but is
> more a "cookbook" idea.
>
>
>
> I have many DiscoveryListener instances in my code, which respond to
> discovered() and discarded() messages for registrars joining and leaving
> the djinn. I like to log which registrar is leaving in the discarded()
> method, but the getLocator() method is remote and I can't invoke it on a
> discarded registrar, obviously. So, I memoize the getLocator() and
> getGroups() methods for my registrars (I know for fact that my
> registrars never change groups or locators in their lifetimes).
>
>
>
> To accomplish this, I created a ProxyPreparer implementation that wraps
> an existing ProxyPreparer (usually BasicProxyPreparer, but not always)
> and adds an additional invocation step. The important parts of the code
> are like the following. I've omitted the constructor that creates
> m_innerProxy from the wrapped ProxyPreparer and I've also omitted some
> boilerplate code that unwraps thrown InvocationTargetException and
> UndeclaredThrowableException instances.
>
>
>
>
>
> private static final Method s_getLocatorMethod;
>
> private static final Method s_getGroupsMethod;
>
> static {
>
> Method getLocatorMethod = null;
>
> try {
>
> getLocatorMethod =
> ServiceRegistrar.class.getMethod("getLocator");
>
> } catch (Throwable e) {
>
> // leave null
>
> }
>
> s_getLocatorMethod = getLocatorMethod;
>
> Method getGroupsMethod = null;
>
> try {
>
> getGroupsMethod =
> ServiceRegistrar.class.getMethod("getGroups");
>
> } catch (Throwable e) {
>
> // leave null
>
> }
>
> s_getGroupsMethod = getGroupsMethod;
>
> }
>
>
>
> private Object m_cachedLocator = null;
>
> private final Object m_cachedLocatorLock = new Object();
>
> private Object m_cachedGroups = null;
>
> private final Object m_cachedGroupsLock = new Object();
>
>
>
> /* (non-Javadoc)
>
> * @see
> java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
> java.lang.reflect.Method, java.lang.Object[])
>
> */
>
> @Override
>
> public Object invoke(Object proxy, Method method, Object[]
> args) throws Throwable {
>
> if (s_getLocatorMethod.equals(method)) {
>
> synchronized (m_cachedLocatorLock) {
>
> if (m_cachedLocator == null)
>
> m_cachedLocator =
> method.invoke(m_innerProxy, method, args);
>
> return m_cachedLocator;
>
> }
>
> } else if (s_getGroupsMethod.equals(method)) {
>
> synchronized (m_cachedGroupsLock) {
>
> if (m_cachedGroups == null)
>
> m_cachedGroups = method.invoke(m_innerProxy,
> method, args);
>
> return m_cachedGroups;
>
> }
>
> } else {
>
> return method.invoke(proxy, method, args);
>
> }
>
> }
>
>
>
>
>
>
>
> Chris Dolan
> Principal Software Engineer | P&S Integrated Media Enterprise
>
> Avid
> 6400 Enterprise Ln, Madison WI 53719
> United States
> christopher.dolan@avid.com<ma...@avid.com>
>
> t 608-288-5104
>
> We're Avid. Learn more at www.avid.com<http://www.avid.com>
>
>
>
>