9 Replies Latest reply on Nov 29, 2004 11:29 AM by Bela Ban

    YACL  (Yet Another CacheLoader) question

    Erik Svensson Newbie

      Howdy all,

      I'm (still) implementing a cache loader and trying to get a feel for how it works.
      I'm wondering about TreeCache.get(Fqn). It does not seem to call CacheLoader.get(Fqn) (which it should in my opinion).

      My code:

      TreeCache cache = new TreeCache();
      .
      .
      Node node = cache.get(new Fqn("top_node");

      I trace the excution to TreeCache.findNode() and to this snippet:

      // try CacheLoader if node is not in cache
      if(child_node == null && cache_loader != null) {
      try {
      if(cache_loader.exists(fqn)) {
      child_node=n.createChild(child_name, tmp_fqn, n, UNINITIALIZED, null);
      notifyNodeLoaded(tmp_fqn);
      }
      }

        • 1. Re: YACL  (Yet Another CacheLoader) question
          Bela Ban Master

          2 solutions if you can't wait:

          #1 Change the code in 1.1.1

          #2 Check out 1.2 from CVS (1 bug remains to be fixed though with non-shared CacheLoaders):
          cd jboss-head/build
          build.sh
          cd ../cache/output/lib
          cp jboss-cache.jar JBOSS_HOME/server//lib

          • 2. 3856892
            Erik Svensson Newbie

             

            "jiwils" wrote:
            I have some code that uses "getChildrenNames", and this works well except when other threads via the same VM (or a remote one upon replication) change the children a node has by removing or adding children.

            The issue is that to use a set, you need to use an iterator. When the underlying set is modified, the iterator properly throws a ConcurrentModificationException. To avoid this, I attempted to use the "toArray" method on the returned set, but this suffers from the same problem.

            In other code where I have used iterators, I have used the "clone" method to avoid this problem, but since the Set interface is returned by this method, I can not use that. I tried to see the type actually returned through "getClass().getName()", but it is an UnmodifiableSet returned from the Collections class, and it does not implement Cloneable either.

            Can anyone suggest a course of action to take? I do not care if what I get back remains up to date as changes are made to the cache node, I only care that it is up-to-date when I invoke "getChildrenNames".



            Although the set in unmodifiable for the caller, the cache itself can modify it. You should copy the set immediately, e.g.

            Set children=new TreeSet(result), no need for a clone().

            • 3. 3857036
              Bela Ban Master

              The 4.0.1RC1 release is available from:
              JBoss-4.0.1 Files

              Release notes are available form here:
              Changes between 4.0.1RC1 and 4.0.0

              The current 4.0.1 target release date is Nov 19. The tasks to be completed for this release and their status are tracked in the following todo forum topic:
              4.0.1 Release Tasks

              • 4. Re: YACL  (Yet Another CacheLoader) question
                Erik Svensson Newbie

                Is there a specific reason why my posting was truncated?
                Is there something wrong with the forum code?

                /Erik

                "nine_mirrors" wrote:
                Howdy all,

                I'm (still) implementing a cache loader and trying to get a feel for how it works.
                I'm wondering about TreeCache.get(Fqn). It does not seem to call CacheLoader.get(Fqn) (which it should in my opinion).

                My code:

                TreeCache cache = new TreeCache();
                .
                .
                Node node = cache.get(new Fqn("top_node");

                I trace the excution to TreeCache.findNode() and to this snippet:

                // try CacheLoader if node is not in cache
                if(child_node == null && cache_loader != null) {
                try {
                if(cache_loader.exists(fqn)) {
                child_node=n.createChild(child_name, tmp_fqn, n, UNINITIALIZED, null);
                notifyNodeLoaded(tmp_fqn);
                }
                }


                • 5. Re: YACL  (Yet Another CacheLoader) question
                  Erik Svensson Newbie

                  Since my original posting was truncated, here comes the rest:

                  it executes the n.createChild(...) but never calls the CacheLoader to get the data. Do I misunderstand what the TreeCache.get(Fqn) method is supposed to do (ie fetch the data from 2nd store if not available in the local cache)?
                  I'm rather confused at this point.

                  Also, looking at the TreeCache code it seems like TreeCache.get(Fqn, key) would result in calling CacheLoader.get(Fqn) which means that I could use this method instead. On the other hand this only increases my confusion.

                  Grateful for any help

                  Erik Svensson

                  • 6. Re: YACL  (Yet Another CacheLoader) question
                    Bela Ban Master

                    This may be a bug in 1.1, but it is definitely calling the CacheLoader in 1.2:

                    public Node get(Fqn fqn) throws CacheException {
                     MethodCall m=new MethodCall(getNodeMethodLocal, new Object[]{fqn});
                     return (Node)invokeMethod(m);
                     }


                    The invokeMethod() passes the call through the interceptor chain, one of the interceptors is the CacheLoader.
                    Can you try with 1.2 (either from CVS head, or wait until mid December) ?


                    Bela

                    • 7. Re: YACL  (Yet Another CacheLoader) question
                      Bela Ban Master

                      BTW: once you have a Node, note that if you update it, the method calls are not intercepted, therefore all the properties provided by the interceptors (locking, cacheloading, replication etc) are not applied !

                      Bela

                      • 8. Re: YACL  (Yet Another CacheLoader) question
                        Bela Ban Master

                        What you can do as a workaround is:

                        cache.getKeys("/a/b/c");
                        Node n=cache.get("/a/b/c");


                        then the node n will have read its attributes from the CacheLoader.

                        Bela

                        • 9. Re: YACL  (Yet Another CacheLoader) question
                          Erik Svensson Newbie

                           

                          "bela@jboss.com" wrote:
                          This may be a bug in 1.1, but it is definitely calling the CacheLoader in 1.2:
                          public Node get(Fqn fqn) throws CacheException {
                           MethodCall m=new MethodCall(getNodeMethodLocal, new Object[]{fqn});
                           return (Node)invokeMethod(m);
                           }


                          The invokeMethod() passes the call through the interceptor chain, one of the interceptors is the CacheLoader.
                          Can you try with 1.2 (either from CVS head, or wait until mid December) ?


                          Bela


                          I've checked out jboss-head and rebuilt it. Calling the cache loader is now done from the interceptor.
                          However, is calling TreeCache.get(Fqn) supposed to result in a call to CacheLoader.get(Fqn) if the node doesn't exist or the map empty?

                          If invoke is called with the source method GetNodeMethodLocal then load_attributes is NOT set to true.

                          /Erik
                          ps somehthing seems to be screwed with this forum (behaviour-wise). I tried to pm you byt that doesn't work.