1 2 3 Previous Next 35 Replies Latest reply on Jul 31, 2006 5:38 AM by galder.zamarreno Go to original post
      • 15. Re: Reactivating SharedStoreCacheLoader
        brian.stansberry

        I'm confused about what pushStateWhenCoordinator does -- doesn't it mean taking all in-memory state and doing a write-through to the cache loader?

        _getState doesn't provide that kind of behavior.

        • 16. Re: Reactivating SharedStoreCacheLoader
          galder.zamarreno

          Basically, when a node which has control over the singleton cache loader dies or leaves the cluster, another node needs to take the responsability for updating this cache loader. Now, this cache loader could be in a different machine or there could be updates in between the old node crashing and the new node taking over the role of the coordinator.

          pushStateWhenCoordinator makes the new coordinator dump the entire in-memory state into the cache store so that it contains a true reflection of what's in memory.

          Looking at the code, it seems like _getState can actually return all the in-memory state. The cache loader would then call storeEntireState(byte[] state) on the underlying cache loader. However, I'm not sure whether about _getState and some of the parameters.

          • 17. Re: Reactivating SharedStoreCacheLoader
            brian.stansberry

            No, this won't work. The byte[] returned by _getState() is made up of subsidiary byte[]s for the in-memory state and the persistent state. The _setState method is responsible for parsing these out and doing the appropriate stuff with each, including passing the *persistent* state to the cache loader. But CacheLoader.storeEntireState() only knows how to handle the persistent state.

            Actually, as I wrote this I realized that for 1.2.4 I did work to make the data format of the in-memory transfer and the persistent transfer consistent. So *maybe* it will work -- you parse out the the in-memory state and pass it to the cache loader.

            This is bad though -- the fact that the data structure of the persistent state and the in-memory state is the same is 1) not part of any interface contract, and therefore 2) if true for the cache loaders we ship with, it's only because *we* wrote them that way. Other custom implementations may be different.

            Re: the timeout and force parameters. I've no opinion on whether the timeout should be configurable, or whether you should just use StateTransferTimeout. The combination of "timeout" and "force" was meant to allow the calling code to loop with a successively longer timeout; on the final iteration of the loop, "force" would be set to true, and at that point _getState would force the breakage of any locks in order to ensure the transfer goes through. Perhaps you should follow a similar approach.

            • 18. Re: Reactivating SharedStoreCacheLoader
              galder.zamarreno

              Brian, is there anything you would suggest then? I can't see an easy solution to the problem you are stating. I will need to look at the exact details of those methods to see what I can do.

              • 19. Re: Reactivating SharedStoreCacheLoader
                galder.zamarreno

                Or alternatively, avoid byte[] states and use navigation methods that would not trigger the cache loader. However, this is likely to be slower.

                • 20. Re: Reactivating SharedStoreCacheLoader
                  brian.stansberry

                  Well, one thought is that going to 2.0 gives us the freedom to specify in the CacheLoader contract what the format of the data passed to storeEntireState has to be. So, we theoretically could take the in-memory state and pass it to storeEntireState. But we'd all have to think very long and very hard about doing that, as we'd have to live by the contract as much as anyone.

                  • 21. Re: Reactivating SharedStoreCacheLoader
                    galder.zamarreno

                    Brian, you're right. Looking at the code in _setState, it seems like that:

                    - The persistent state actually comes from calling CacheLoader.loadEntireState() or CacheLoader.loadState(). So the origing of the persistent state is the CacheLoader.

                    - The transient(in-memory) state comes from marshalling the transient state (or marshall the associated state for PojoCache) generated inside the StateTransferGenerators.

                    Therefore, we can control the in-memory state but we are can't really control the persistent state (with the current rules).

                    In my opinion, rather than making both states consistent, the CacheLoader should be able to generate a persistent state given the in-memory state. However, in order for this to work, the structure of the in-memory state would need to be made public so that potential CacheLoader implementors could transform it into the persistent state that we're after.

                    • 22. Re: Reactivating SharedStoreCacheLoader
                      manik

                      Hmm, that would involve rewriting the current set of cache loaders. I'm concerned about feasibility wrt. timescales here.

                      • 23. Re: Reactivating SharedStoreCacheLoader
                        galder.zamarreno

                        That is indeed true.

                        However, let's say the method looked something like this:

                        public byte[] createPersistentState(byte[] inMemoryState, FQN root)
                        


                        The current CacheLoaders would just need to return the result of loadState(root) or loadEntireState() depending on the number of elements in the root node.

                        The main problem I see is that even if you only wanted to generate the persistent state, you'd require to parse the in-memory state as well.

                        • 24. Re: Reactivating SharedStoreCacheLoader
                          galder.zamarreno

                          If we wanna add a new method to CacheLoader, this is going to be the last chance before 3.x I guess?

                          • 25. Re: Reactivating SharedStoreCacheLoader
                            manik

                             

                            Well, one thought is that going to 2.0 ...


                            This needs to be backported to 1.2.4 as well.

                            • 26. Re: Reactivating SharedStoreCacheLoader
                              manik

                              What about something like this -

                              1) New node becomes coord
                              2) Triggers a process in the singleton cache loader to take over ownership of the singleton cache.
                              3) Starts by walking the tree to get a picture of the in-memory state (by doing _get? Bad, since no locks are obtained. Perhaps by passing in a flag to bypass cache loading?)
                              4) Make calls to cacheLoader.put() for each node visited in the tree.

                              Yes, this is brute-force and slower than getting/setting state as bytes, but at least this sticks with data format contracts without having to make assumptions.

                              Thoughts?

                              • 27. Re: Reactivating SharedStoreCacheLoader
                                brian.stansberry

                                I think what you propose is the way to go and may not be particularly slower than using the byte arrays. In the end a state transfer of in-memory state involves walking the tree on the side providing the state, and storing persistent state involves executing the cache loader's code for storing each node. The byte arrays just package up the data for efficient transmission over the wire.

                                • 28. Re: Reactivating SharedStoreCacheLoader
                                  galder.zamarreno

                                  I'm coding the state transfer so that I use cache's get() methods to get the in-memory state and call put on the cache loader (this will happen just before I set the cache loader as "active" (meaning it's the singleton). By doing this, this get methods won't make calls to the underlying cache loader).

                                  Secondly, how shall we treat exceptions thrown during this state transfer? Shall we just log them as errors? These calls happen inside TreeCacheListener.viewChange() so it's either that or throw a RuntimeException.

                                  • 29. Re: Reactivating SharedStoreCacheLoader
                                    galder.zamarreno

                                    Ok, forget what I said about when to set the cache loader as active. These needs to be done a before doing the state transfer, othewrise, I won't be able to actually call the put operations in the underlying loader.