13 Replies Latest reply on Nov 14, 2006 1:04 PM by Elias Ross

    Document where non-String FQN do not work, JBCACHE-838

    Elias Ross Master


      (From the issue)

      Clearly, Region names are supposed to be described using String-only FQNs. This is because Regions are configured using String names in their configuration.

      Also, the file and JDBC based persistence system do not handle non-String FQNs.

      But here are several use cases for using non-String FQN.

      For example, at my past company, we stored mobile handset data by country code and phone numbers as numbers. Things like integers and enumerated types are obviously more lightweight than string objects as keys. Personally, I think that being able to use appropriate types in the FQN is worthwhile efficiency and is more consistent with the Java philosophy of type safety.

      In any case, it would be nice to have an audit of areas that:
      0. Do support non-String FQN by design.
      1. Do not support non-String FQN, but possibly could (create new issues for these?).
      2. Cannot support non-String FQN, and are not documented.

        • 1. Re: Document where non-String FQN do not work, JBCACHE-838
          Brian Stansberry Master

          +1 on not restricting to String if where we can get around it.
          +10 on better documenting the limitation.

          I think the String limitation for Region comes from the old o.j.c.marshall.Region. This limitation was added because the Fqn was used in the marshalling code by a message recipient to determine what classloader to use to deserialize the message. That led to a chicken-or-egg problem: if one of the objects in the Fqn itself required the classloader, you were out of luck.

          Solving that problem didn't really require use of String only. It just requires that no classes not visible to TreeCacheMarshaller.class.getClassLoader() be used in the Region Fqn. That's significantly less restrictive and can be documented.

          JGroups partial state transfer adds a new problem in that the JGroups API requires use of String instead of Object as the identifier of the partial state. It would be nice if that were changed in a later release., although as an API change it would probably take a while to work its way into JBC.

          For now, can we think of a way to use a String as a substitute for the Region Fqn in the partial state transfer call? E.g. restrict the components of a Region Fqn to String/Number/Enum, all of which can be fairly safely converted to a String. Or hopefully something more elegant than that :-)

          • 2. Re: Document where non-String FQN do not work, JBCACHE-838
            Ben Wang Master

            The other restriction as mentioned is the eviction policy (as a region). But that can be relaxed now providing a user configures the region programatically.

            • 3. Re: Document where non-String FQN do not work, JBCACHE-838
              Manik Surtani Master

               


              The other restriction as mentioned is the eviction policy (as a region). But that can be relaxed now providing a user configures the region programatically.


              Well, the majority of eviction policy regions I have seen in production are configured in XML. And I think this is the better approach too.

              • 4. Re: Document where non-String FQN do not work, JBCACHE-838
                Manik Surtani Master

                 



                For now, can we think of a way to use a String as a substitute for the Region Fqn in the partial state transfer call? E.g. restrict the components of a Region Fqn to String/Number/Enum, all of which can be fairly safely converted to a String. Or hopefully something more elegant than that :-)



                Well, the problem here is that writing an Integer or Enum as a String is alll nice and easy, but re-serializing is tougher.

                Basically, Fqns containing {"test", "1"} will look the same as {"test", new Integer(1)} if serialized to Strings. How do you know which to deserialize to, to identify the region to apply the partial state to? What if they both exist in the same tree?

                • 5. Re: Document where non-String FQN do not work, JBCACHE-838
                  Brian Stansberry Master

                   

                  Basically, Fqns containing {"test", "1"} will look the same as {"test", new Integer(1)} if serialized to Strings. How do you know which to deserialize to, to identify the region to apply the partial state to? What if they both exist in the same tree?


                  Sure, that's a problem. But I think it's a documentable problem. And it exists at the Region level, which would typically be something an app developer would think about a little bit. Having two different region Fqn's that resolve to the same string would be sign of a stupid app design.

                  Kind of a philosophical issue -- do you restrict what people can do because you're concerned people will do boneheaded things? I'm generally opposed to that, particularly when the odds of the boneheaded behavior are low.

                  Of course if we can't solve technical problems like the String in the JG partial state transfer API, that's a different thing.

                  • 6. Re: Document where non-String FQN do not work, JBCACHE-838
                    Manik Surtani Master

                     


                    Sure, that's a problem. But I think it's a documentable problem. And it exists at the Region level, which would typically be something an app developer would think about a little bit. Having two different region Fqn's that resolve to the same string would be sign of a stupid app design.


                    Agreed, but it still doesn't solve the problem of what should {"test", "1"} resolve to. 2 strings, or a string and an integer? Even if there is both don't exist in the same tree (that was an extreme example), you still don't know how to deserialize as both could be equally correct.

                    • 7. Re: Document where non-String FQN do not work, JBCACHE-838
                      Brian Stansberry Master

                      The partial state transfer finds the Region by iterating, calling Fqn.toString() on the various regions and matching on that.

                      Ugly, sure. And CacheSPI would need to expose an API to let that happen. It now exposes getEvictionRegionManager(), which I assume will be replaced.

                      I've been asking myself why I'm arguing about this general area and proposing hacky solutions. It's because I don't see any reason why the JGroups partial state transfer API needs to limit the state id to type String. I think that will be changed someday. So I'm concerned about JBC building in all sorts of limitations based on it.

                      IMHO what we should do is resolve why the JGroups API is limited to String and determine if and when that will change. Then decide what to do based on that knowledge. If based on that we decide to add in a few hacks to deal with the current API, I think that might be OK.

                      • 8. Re: Document where non-String FQN do not work, JBCACHE-838
                        Manik Surtani Master

                        I agree. That should be the starting point here, and from there on, decide on whether we need a temporary layer between JG and JBC to force String conversion until JG can handle non-Strings.

                        • 9. Re: Document where non-String FQN do not work, JBCACHE-838
                          Bela Ban Master

                          There's no point in supporting a non-string ID in JGroups for partial state transfer if we cannot support the same in the cache loaders (JDBC, File etc).

                          • 10. Re: Document where non-String FQN do not work, JBCACHE-838
                            Manik Surtani Master

                            Other cache loaders (e.g., remote TCP cacheloaders) can support these though.

                            • 11. Re: Document where non-String FQN do not work, JBCACHE-838
                              Elias Ross Master

                              The JDBM cacheloader does support non-string FQN.

                              BDBJE does not, but could by doing something like:

                              TupleOutput to = new TupleOutput();
                              Fqn fqn = ...
                              fqn.writeExternal(to);
                              


                              Actually, this would be a nice feature worth adding by having this configured by the cache configuration.

                              • 12. Re: Document where non-String FQN do not work, JBCACHE-838
                                Manik Surtani Master

                                And such 'binary' tuples can be searched on? Any idea what the performance impact on this must be like?

                                • 13. Re: Document where non-String FQN do not work, JBCACHE-838
                                  Elias Ross Master

                                  The database works off of byte arrays. I'm guessing performance would be slower, becauase serialization makes a fatter byte array. But probably performance would not be significantly worse since any sort of disk I/O is always a magnitude or two slower anyway.

                                  Again, it could simply be an option.