10 Replies Latest reply on Feb 3, 2006 7:04 AM by manik

    Cach activations seem to do excessive database operations

      When implementing the ActivationsInterceptor mbean, I found that the activations count was much larger than I expected. I assumed that an activation would only occur if I tried to read a node that had been previously evicted. However it looks like an activation occurs whenever I try to read any node with activations enabled.

      In the following example, I'm writing one node with a key. I'm not evicting it or passivating it at all.

      tree.put("node5", new HashMap());
      tree.put("node5", "key5", "value5");
      tree.get("node5", "key5");
      tree.get("node5", "key5");
      tree.get("node5", "key5");

      This code snippet generates 5 activation operations; each of these operations accesses the database to try to remove an entry for fqn=/node5.

      Is this correct processing?

        • 1. Re: Cach activations seem to do excessive database operation

          Forgot to note that I'm using JDBCCacheLoader as my backing store.

          • 2. Re: Cach activations seem to do excessive database operation
            hmesha

            on the get the activation interceptor suppose to look up the cache loader and if the node exists then it loads into memory, remove it from cache loader store and emits an activation notification.

            I'm not sure why there's action on put() in the activtion interceptor though. I remember when I first implemented the interceptor there wasn't.

            -Hany

            • 3. Re: Cach activations seem to do excessive database operation

               

              on the get the activation interceptor suppose to look up the cache loader and if the node exists then it loads into memory, remove it from cache loader store and emits an activation notification.


              Looks like this is happening on every get operation. I'll look closer at the interceptor.


              • 4. Re: Cach activations seem to do excessive database operation

                The problem is that the activation interceptor currently can't detect whether the node was already in memory or had to be retrieved from the backing store. So it processes all get operations as activations as long as the node has been found somewhere.

                It's unclear why puts and removes are also processed as activations.

                I'm looking for a way for the cache loader interceptor to communicate the necessary information to the activation interceptor so that we can eliminate the unnecessary processing on gets from memory.

                • 5. Re: Cach activations seem to do excessive database operation
                  hmesha

                  The removes need to be handled in the passivation interceptor. If the user calls cache.remove() and the node has been passivated, we need to remove it from the passivation store. That was the case when I implemented the passivation/activation feature but looking at the current version I don't see that happening.

                  • 6. Re: Cach activations seem to do excessive database operation

                    The "remove" logic should be in the activation interceptor, not the passivation interceptor, right? The activation interceptor removes entries from the backing store while the passivation interceptor writes them to the store.

                    So maybe that's why the activation interceptor processes remove operations.

                    • 7. Re: Cach activations seem to do excessive database operation
                      hmesha

                      Right. I was mistakenly looking in the wrong place.

                      • 8. Re: Cach activations seem to do excessive database operation

                        I've found a simple solution but am unsure whether it's susceptible to cache threading problems.

                        The Activation interceptor extends CacheLoader interceptor. When invoke(MethodCall) is called on the Activation interceptor, it calls super.invoke(MethodCall) to execute invoke on CacheLoader and it then proceeds with activation processing as required.

                        I can add a protected boolean instance variable "nodeLoaded" to CacheLoader to indicate whether the node was loader via an external cache loader. The variable will be set in the invoke method. On return to the Activation interceptor, the variable can be read (i.e., because ActivationInterceptor extends CacheLoaderInterceptor) and processing can proceed based upon the value of this variable.

                        I am susceptible to cache threading problems if I set the variable in one method and then read it in another? I don't want to synchronize the entire interceptor stack which is what I think would happen if I synchronized on invoke(MethodCall) and then read the setting in the synch block.

                        Any ideas?

                        • 9. Re: Cach activations seem to do excessive database operation
                          manik

                          You will be susceptible to threading problems. I think the solution you want is to use a protected ThreadLocal instance variable on CacheLoaderInterceptor to hold the boolean flag.

                          • 10. Re: Cach activations seem to do excessive database operation
                            manik

                            You will be susceptible to threading problems. I think the solution you want is to use a protected ThreadLocal instance variable on CacheLoaderInterceptor to hold the boolean flag.