4 Replies Latest reply on Dec 9, 2011 7:31 PM by sannegrinovero

    CacheLoader: N cache entries vs 1 db row and vice-versa

    ydewit

      Consider the specific case where I have Parent and Child objects in my app (that I want to store in the cache) and a database that stores these as a blob(Parent+N children) in a row keyed by Parent ID. Assuming that from a Child object I can get the Parent ID, I would like to have a CacheLoader that can:

      1. update the blob when Parent or Child entries in the cache change

      2. read Parent and Children from the db when the Parent or a Child is read (and don't exist in the cache).

       

      In order to do (1), the CachelLoader needs to be able to query the cache for the children or the parent while being asked to store a Parent or a Child, respectively. And for (2), the CacheLoader needs to be able to insert a new Parent and children while being asked to load a Parent or any of the children.

       

      First of all, is this scenario accounted for in the design of the CacheLoader/Store or am I trying to bend the rules here?

       

      Is there a way to get/put entries in/from the cache bypassing the CacheLoader/Store to avoid it reentering the CacheLoader/Store? My preliminary experiments shows that it seems possible as long as I am careful to avoid an infinite loop.

       

      Any different ways I could achieve the same?

       

      thanks!

        • 1. Re: CacheLoader: N cache entries vs 1 db row and vice-versa
          sannegrinovero

          Hi Yuri,

          yes you're bending the rules as I think this wasn't attempted before, but I think it should work. Obviously you'll have to implement your very own custom CacheLoader.

           

          To avoid looping, make sure you look at the Flags you can enable on an AdvancedCache, as there are flags to ignore the CacheLoader(s).

           

          cache.getAdvancedCache().withFlags(...)

           

          Interesting idea, please let us know if you manage that.

          Of course we're open to both patches and suggestions to make the CacheLoader API more flexible in case you need.

          • 2. Re: CacheLoader: N cache entries vs 1 db row and vice-versa
            ydewit

            Sanne,

             

            Ok, always good to know where I am treading before I take the first step. I will ping if I get stuck somewhere.

             

            Thanks re: the withFlags() API. I see that it is implemented as a ThreadLocal so does Ipsn automatically clears it for me or I am responsible for explicitly unsetting Flag.SKIP_CACHE_LOAD/Flag.SKIP_CACHE_STORE? I guess I better head to the RTFM room.

             

            best.

            • 3. Re: CacheLoader: N cache entries vs 1 db row and vice-versa
              ydewit

              Forgot to ask one more thing: I am assuming that if I put() N entries while the CacheLoader is trying to load 1 that, the N entries participate in the same transaction, if any, and that cache replication/distribution/invalidation will happen the same, right?

               

              One last question: what would be the best CacheLoader base class to use? I am using AbstractCacheStore since I am assuming I don't need the locking provided by LockSupportCacheStore (the db will provide that for me).

               

              thanks.

              • 4. Re: CacheLoader: N cache entries vs 1 db row and vice-versa
                sannegrinovero

                Thanks re: the withFlags() API. I see that it is implemented as a ThreadLocal so does Ipsn automatically clears it for me or I am responsible for explicitly unsetting Flag.SKIP_CACHE_LOAD/Flag.SKIP_CACHE_STORE? I guess I better head to the RTFM room.

                That API changed in 5.1: new version is that withFlags() returns a different Cache instance which will apply those flags permanently, so you should try to reuse the Cache instance. Seems a good fit for your case: enable both flags, then all invocations from inside the CacheLoader will be safe.

                 

                In previous version it would affect the next invocation on the same cache, and always cleanup after that, so you would need to specify the flags on each command.

                 

                 

                Forgot to ask one more thing: I am assuming that if I put() N entries while the CacheLoader is trying to load 1 that, the N entries participate in the same transaction, if any, and that cache replication/distribution/invalidation will happen the same, right?

                CacheLoaders do not participate in the same transaction, not explicitly at least (I guess a sync call to the cacheloader using an application server provided datasource would). You would have to take care of this, and keep in mind that depending on your configuration the activity on the CacheLoader might happen in a different thread than your application invoking the Cache commands.

                 

                 

                One last question: what would be the best CacheLoader base class to use? I am using AbstractCacheStore since I am assuming I don't need the locking provided by LockSupportCacheStore (the db will provide that for me).

                Yes should be fine. There are some more trivial CacheLoaders in the testsuite if you need something simple to start from.