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>
>
>
>
>