5 Replies Latest reply on Apr 10, 2007 5:51 PM by jason.greene

    PojoInstance: ref count & notification

    supi

      Hi, I am trying to build an adapter on top of CacheListener to create (to me useful) Pojo notifications. Unfortunately, I cannot determine if a pojo is being multi-attached or detached because PojoInstance's ref count is the same in local pre and post notification (IMO a bug). The problem is in InternalHelper:

       /**
       * Increment reference count for the pojo. Note that this is not thread safe or atomic.
       */
       int incrementRefCount(Fqn originalFqn, Fqn referencingFqn) throws CacheException
       {
       PojoInstance pojoInstance = getAopInstance(originalFqn);
       if (pojoInstance == null)
       throw new PojoCacheException("InternalDelegate.incrementRefCount(): null pojoReference for fqn: " + originalFqn);
      
       int count = pojoInstance.incrementRefCount(referencingFqn);
       // need to update it.
       put(originalFqn, PojoInstance.KEY, pojoInstance);
       return count;
       }
      


      It is stated that the method is not thread safe but the instance's incrementRefCount and decrement methods are in fact synchronized. So, can I just clone the instance, increment and put or do I need to synchronize the whole thing? Shouldn't it be locked anyway, where does this happen? Are there any other effects that I should be aware of that prevent us from doing:
       PojoInstance updatedInstance = (PojoInstance)pojoInstance.clone();
       int count = newInstance.incrementRefCount(referencingFqn);
       // need to update it.
       put(originalFqn, PojoInstance.KEY, updatedInstance);
      


      Thanks,
      Basil



        • 1. Re: PojoInstance: ref count & notification
          jason.greene

           

          "supi" wrote:
          Hi, I am trying to build an adapter on top of CacheListener to create (to me useful) Pojo notifications. Unfortunately, I cannot determine if a pojo is being multi-attached or detached because PojoInstance's ref count is the same in local pre and post notification (IMO a bug). The problem is in InternalHelper:


          Can you expalin in more detail and possiblly show a code example of how you noticed this? InternalHelper does correctly dispatch to PojoInstance to increment the counter. There was however a bug I recently fixed that would cause any serializable object that was accessed on a remote node to possible see a stale copy. Although keep in mind that currently notifications only trigger on the local node that produced the change.


          It is stated that the method is not thread safe but the instance's incrementRefCount and decrement methods are in fact synchronized. So, can I just clone the instance, increment and put or do I need to synchronize the whole thing? Shouldn't it be locked anyway, where does this happen?


          You should not have to clone the instance. Does cloning fix the problem for you? If so you are likely seeing the bug I mentioned earlier (a current cvs checkout should solve the issue). As far as locking is concerned, there is an outter lock held by ObjectGraphHandler.

          -Jason

          • 2. Re: PojoInstance: ref count & notification
            supi

            Unfortunately, I don't have CVS access right now, and not much time either.

            But to clarify (I don't think it's the serialization issue):

            1) I'm not talking about attach/detach notifications provided by PojoCacheListener because they don't currently work for remote changes and also don't provide all the information I need. Right now, I'm building my own POJO notification adapter. This is simply a stateful CacheListener (not a PojoCacheListener) that converts pre and post node modified notifications into attach/modify/detach (I like the concept), and whether this is an initial attach or the last detach.

            2) For this to work, PRE must really be PRE, especially in the case of reference counts. If you do:

             int count = pojoInstance.incrementRefCount(referencingFqn);
             // need to update it.
             put(originalFqn, PojoInstance.KEY, pojoInstance);
            


            the local pojoInstance object is already changed before you issue the put (incrementRefCount not intercepted).

            To check this, you can simply add a cache listener to a pojo cache's base cache and print data of local node modified events. By cloning the object, node modified (PRE) actually contains the ref count before changing it.



            • 3. Re: PojoInstance: ref count & notification
              jason.greene

              Ah I assumed you were using the pojo notification framework. Yeah this is by design. Any mutable object that is serializable will have visible changes since the object isn't serialized until the transaction commits. So a cache listener will only see identity changes, and not a true state change.

              Assuming that remote pojo notifications worked, what information are you missing? I plan to fix all notification issues (including remote delivery) by GA, so if the design is missing something you need I would like to know. If you can't wait, and need to implement your own solution I understand, but do keep in mind that the internal structure isn't considered public, so it may change in the future.

              Why do you need to know if an object is multiply referenced?

              Regarding your change, a safer solution would be to add whatever information you need as independent internal properties.

              Also, everyone has access to our anonymous cvs server:

              cvs -d :pserver:anonymous@anoncvs.forge.jboss.com:/cvsroot/jboss login
              (hit enter for password)
              cvs -d :pserver:anonymous@anoncvs.forge.jboss.com:/cvsroot/jboss co JBossCache
              


              -Jason

              • 4. Re: PojoInstance: ref count & notification
                supi

                 

                "jason.greene@jboss.com" wrote:

                Regarding your change, a safer solution would be to add whatever information you need as independent internal properties.

                Yes, I agree.


                Assuming that remote pojo notifications worked, what information are you missing? [...]
                Why do you need to know if an object is multiply referenced?


                Basically, your second question is the answer to the first one. I simply need to know whether this is the first attach or not and also if it is the last detach or not. Depending on this flag (in my interface, the two methods look like this:
                public void attach(Object inObject, boolean inIsFirst, boolean inIsLocal);
                public void detach(Object inObject, boolean inIsLast, boolean inIsLocal);
                

                and are always post), an external processing unit can create related information, delete it, or do nothing. Of course, it would be great if something like this could be included. Unfortunately, I really need it now and my solution seems to work for the moment. It just bothers me that I had to change some of the internals (OTOH, I could also always switch to an entirely external reference counting scheme).

                Cheers,
                Basil


                • 5. Re: PojoInstance: ref count & notification
                  jason.greene

                   

                  "supi" wrote:

                  Basically, your second question is the answer to the first one. I simply need to know whether this is the first attach or not and also if it is the last detach or not. Depending on this flag (in my interface, the two methods look like this:
                  public void attach(Object inObject, boolean inIsFirst, boolean inIsLocal);
                  public void detach(Object inObject, boolean inIsLast, boolean inIsLocal);
                  

                  and are always post), an external processing unit can create related information, delete it, or do nothing.


                  Ok, I understand your case, so I will add something similar. Although we might want to introduce some kind of context object that would contain useful information like this.


                  Of course, it would be great if something like this could be included. Unfortunately, I really need it now and my solution seems to work for the moment. It just bothers me that I had to change some of the internals (OTOH, I could also always switch to an entirely external reference counting scheme).


                  Understood. Well your approach is perfectly valid, so if you make whatever internal changes you need (modifying increment/decrementRefCount to add another attribute should solve your issue), and just let us know the features, we can get something similar in place that should be an easy migration. I would like to work out all design kinks by GA since after that point we have to worry about BC.

                  -Jason