1 2 Previous Next 20 Replies Latest reply on Jul 18, 2007 5:32 AM by manik

    uninitialized nodes

    aditsu

      Hi, I'm using jboss-cache 1.4.1.SP3; I'd like to understand when and especially why some nodes are marked as uninitialized.

      When the app starts, I insert some data into the cache (using put(Fqn, Map)), but it looks like the maps get added an extra key ("jboss:internal:uninitialized") which leads to 2 things I definitely do NOT want:
      - when I try to get a node, the cache goes to the cacheloader to load the data (although it is already in memory)
      - when I use getChildren, the child nodes are retrieved with the extra key in their data map, which wreaks havoc in the app logic

      Here's some details about the cache configuration:
      - mode = REPL_SYNC
      - isolation = READ_COMMITTED
      - no eviction policy
      - no passivation

        • 1. Re: uninitialized nodes
          genman


          JBoss Cache 2 (which is not in release yet) fixes some problems, such as the "hack" where the map storage is used for book-keeping information.

          This key is used to indicate that the data has not yet been loaded from disk. You say this data is "already in memory", how do you know? Also, the children are not loaded with their data until they are accessed. This is a feature not a bug.

          Some of the problems with JBCache 1.4 are caused by accessing data via the Node object and not the Cache object.

          • 2. Re: uninitialized nodes
            aditsu

            > You say this data is "already in memory", how do you know?

            Because I first put it myself in the cache. The data map already present in the cache node (I checked with peek) has all the information I need, plus the jboss:internal:uninitialized key which I don't need. When the cache finds that key, it decides to load data from the cacheloader.

            > Also, the children are not loaded with their data until they are accessed. This is a feature not a bug.

            Well, I am calling getChildren() on a node, then getData() on the resulting map's values. Again, I get the data I want with that extra key added. Am I doing it the wrong way?

            > Some of the problems with JBCache 1.4 are caused by accessing data via the Node object and not the Cache object.

            Well, when I put data in the cache, I use the cache object. When I get data (in the first case, without involving children), I use get(Fqn) on the cache object then getData() on the node; I haven't found a better way to get all the node's data.

            I found that if I manually remove the uninitialized key immediately after putting a node in the cache, all the problems seem to disappear. However, this looks like an UGLY thing to do.

            • 3. Re: uninitialized nodes
              manik

              Don't use the Node object directly in JBC 1.x. It was meant to be an internal data structure object that got leaked into the API.

              The correct approach is to use TreeCache.getChildrenNames()

              In 2.x, we fully support access to Nodes, but this is different.

              • 4. Re: uninitialized nodes
                aditsu

                > Don't use the Node object directly in JBC 1.x.

                Ok, I guess I can use getChildrenNames(), but how can I get the data map of a node?
                Anyway, I'm already looking at JBC 2, and I found a lot of nice improvements... maybe we'll switch to that. I'll adapt my code to it and see how it behaves.

                • 5. Re: uninitialized nodes
                  aditsu

                  Well, I have the same problem with jboss-cache-2.0.0.CR2: I put a node in the cache, but when I try to get it later, it tries to load it from the cacheloader because dataLoaded (in UnversionedNode) is false. How can I solve this?

                  • 6. Re: uninitialized nodes
                    genman

                    Node.replaceAll(Map m) should not load the data.

                    Node.putAll() really is a merge operation, which is why the cache will load old data when doing a getData()

                    • 7. Re: uninitialized nodes
                      aditsu

                      In order to call replaceAll, I need to have a Node first. And when I try to get a node, the cache calls the cacheloader to load the data. This is exactly what I want to avoid.

                      • 8. Re: uninitialized nodes
                        aditsu

                        I also found that CacheLoaderInterceptor.loadChildren() actually calls setDataLoaded(false) explicitly on every single child node, ignoring the fact that data was already in memory.
                        It looks like JBC is trying every possible way to make sure that I can never optimize data preloading, and it loads each node separately from the cache loader, even multiple times.

                        • 9. Re: uninitialized nodes
                          aditsu

                          It looks like the solution to all my problems is *not* to use a cacheloader at all. I was preloading all the data anyway (in a custom and optimized way) so I don't need to load further data, and for storing changes I found that I can use a simple cache listener (the JBC2 CacheListener does a wonderful job). I'm using this kind of configuration now.

                          • 10. Re: uninitialized nodes
                            genman


                            Filed this as JBCACHE-1120

                            • 11. Re: uninitialized nodes
                              manik

                              Thanks for this. Yes, this is a bug - JBCACHE-1133.

                              • 12. Re: uninitialized nodes
                                manik

                                Sorry, didn't see 1120 - marking it as a dupe.

                                • 13. Re: uninitialized nodes
                                  manik

                                  From your comment on JBCACHE-1120:

                                  "aditsu" wrote:

                                  I don't think that's what I reported. I actually had these two problems:
                                  - AFTER I PUT A NODE IN THE CACHE, if I try to get the same node from the cache, it still loads its data from the cacheloader
                                  - after I load a node's children for the first time, if I try to get a child node from the cache, it loads its data from the cacheloader, even if it had already loaded it previously

                                  Here's an example, with comments describing what the cacheloader is doing:

                                  Cache c = DefaultCacheFactory.getInstance().createCache("replSync-service.xml", true);
                                  Map m = new HashMap();
                                  m.put("foo", "bar");
                                  Fqn ab = new Fqn("a", "b");
                                  c.put(ab, m); //put /a/b, {foo=bar}
                                  c.get(ab, "foo"); //get /a/b
                                  c.get(ab, "foo"); //(nothing)
                                  Node a = c.getRoot().getChild(new Fqn("a")); //get /a
                                  a.getChildren(); //getchildrennames /a
                                  c.get(ab, "foo"); //get /a/b
                                  c.stop();

                                  So it's loading the /a/b node twice, when normally it should never load it at all (because I put it in the cache first)


                                  This is not entirely correct since even when you first put a node in the cache, it does need to (try and) load it from the cache loader in case it is not really a new node but one that was evicted.

                                  Doing a put(node, key, value) is expected to return the old value under that key and hence the need to load.

                                  Subsequent calls to put and get should not load from the loader until the node is evicted though.

                                  See JBCACHE-1133.

                                  • 14. Re: uninitialized nodes
                                    manik

                                    Also pls see the unit test I've got for this, which emulates the steps you've got in your comment on JIRA:

                                    org.jboss.cache.loader.UnnecessaryLoadingTest

                                    1 2 Previous Next