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
[email protected] <mailto:[email protected]>  

t 608-288-5104 

We're Avid.  Learn more at www.avid.com <http://www.avid.com>  

 

Reply via email to