1 2 Previous Next 19 Replies Latest reply on Jul 20, 2007 6:57 PM by jason.greene

    static field replication in PojoCache

      I am trying to scope out the requirement for the static field replication. Here are what I have:

      1. Create a @Replicatable field annotation so user can annotate the POJO to designate the static field for replication, e.g.,

      @org.jboss.cache.pojo.annotation.PojoCacheable
      public class POJO
      {
       @org.jboss.cache.pojo.annotation.Replicatble
       public static int someStaticVar;
      
       ...
      }
      

      such that
      POJO.someStatic=10
      will trigger the replication.

      2. Only support the static variable of either Primitive or Serializable. I.e., can't support another "aspectized" POJO.

      3. The fqn name for the static field varialbe is global and is known a priori, e.g., in the above case, someStaticVar will be stored under:
      /__JBoss_Static_/POJO/someStaticVar


      4. The static variable will be stored under the cache during POJO initialization (even when no POJO has not been put into the cache yet!)

      5. And finally, there can be only ONE PojoCache instance per VM! This is needed to follow the normal Java semantics. Furthermore, if we have multiple cache instances, which cache instance are we going to store the static variables under?

      Of course, the last requirement is more restrictive and more importantly make the unit testing difficult.

        • 1. Re: static field replication in PojoCache
          genman

          Couldn't you have statics work like this:

          PojoCache c = ...;
          c.registerClass(POJO.class);

          I suppose also you could do some tricks with the classloader, so a classloader would have a PojoCache attached to it. And at the time the class is loaded, it gets registered.

          • 2. Re: static field replication in PojoCache

            Sorry, I don't get it. What will registerClass do to POJO? To start replication?

            Attach to the class loader idea is fine but IMO is making the process more complicated than it should be.

            • 3. Re: static field replication in PojoCache
              genman

              Why are 4 and 5 even good ideas, let alone "requirements"?

              As a user, I would want to specify where the static variable is stored and how and if it is replicated. The "registerClass" would essentially link a class to the cache. A class would have to belong to a single cache.

              To be fair, I'm not really involved with this feature at all. I'm not the customer. But here are what I believe are "requirements":
              1. User needs to be able to specify which PojoCache they are replicating their object with. This is becaues it's a common use case to have multiple PojoCache instances per JVM.
              2. User needs to be able to control (turn on/off) replication of the static fields. It needs to be off by default. This is because they might want to use this object in a situation where they aren't using JBossCache, e.g. on a simple client without JBoss Cache.

              • 4. Re: static field replication in PojoCache
                belaban

                #1 Why do we need to annotate someStaticVar in the first place ? Since the class is tagged as @PojoCacheable (that's a stupid name, let's change it to @Replicated or @Clustered !!), someStaticVar needs to be replicated as well !

                #2 Of course we need to support another static variable ! Ideally we adhere to the Java semantics

                #3 Sure. Implementation issue correct ?

                #4 Or lazy, whatever. Implementation issue again

                #5 Why ? we can have N someStaticVars per *cluster*...

                • 5. Re: static field replication in PojoCache

                   

                  "genman" wrote:
                  Why are 4 and 5 even good ideas, let alone "requirements"?

                  Yeah, sorry, just missed typing the "restriction" part.


                  As a user, I would want to specify where the static variable is stored and how and if it is replicated. The "registerClass" would essentially link a class to the cache. A class would have to belong to a single cache.


                  Le'ts say we change your api naming first to "registerStaticVariableClass" to be more verbose. An additional api like that (and possibly unregisterStaticVariableClass) is certainly ok but like I mentioned it adds additional APIs to PojoCache, of which I'd like to avoid if possible, especially this won't be used often.

                  Furthermore, there are 2 pitfalls:

                  1. There are some dependency on the static variable lifecycle. Consider this:
                  POJO.someStaticVar = 20; // setting but no replication yet.
                  cache = PojoCacheFactory.createCache(...);
                  cache.registerStaticVariableClass(Pojo.class);
                  // Still no POJO.someStaticVar replication yet unless we do
                  // POJO.someStaticVar = 30; to trigger replication.
                  // But now we failover to the other node and do
                  int val = POJO.someStaticVar; // this is not 20!
                  

                  Of course this probably doesn't happen often but there is the possibility.

                  2. You will need to invoke this API in every cache instance in the clustering group (even the others are merely acting as passive backup) in order for it be funtion properly. E.g., cache1 and cache2 will need individually:
                  cache = PojoCacheFactory.createCache(...);
                  cache.registerStaticVariableClass(Pojo.class);
                  

                  Otherwise, when you failover, the remote cache will have no knowledge of interceptiong the


                  1. User needs to be able to specify which PojoCache they are replicating their object with. This is becaues it's a common use case to have multiple PojoCache instances per JVM.


                  There are 2 difference cases for multiple PojoCache instances inside same vm:

                  1. Different clustering groups, e.g., one cache instance for http and another one for ejb, and furthermore the all use the same POJO static variable.

                  a) They don't share the same POJO.statVar field and expect it to be replicated to a specific cache instance. In this case, only a specific cache instance is needed to replicate the static variable. Yes, we should support this fashion of usage.

                  b) Both cache instances access the same POJO.someStaticVar and still expect only replicating the staticVar to a specific PojoCache instance, e.g., http one (but not the ejb one). This does not follow the regular Java semantics and IMO, I can't think of a use case for that now.

                  2. Same clustering groups, e.g., 1 VM has cache1 and cache2 but same jgroups channel. This is happening a lot in testing but is there other real life usage?



                  2. User needs to be able to control (turn on/off) replication of the static fields. It needs to be off by default. This is because they might want to use this object in a situation where they aren't using JBossCache, e.g. on a simple client without JBoss Cache.


                  You are asking for fine-grained, runtime control to decide when to replicate and not. But I am thinking more of global wide cache control via POJO field annotation, @Replicatable. That is, if cache is declared properly and POJO is declared as well, then some static field replication will happen.



                  • 6. Re: static field replication in PojoCache

                     

                    "bela@jboss.com" wrote:
                    #1 Why do we need to annotate someStaticVar in the first place ? Since the class is tagged as @PojoCacheable (that's a stupid name, let's change it to @Replicated or @Clustered !!), someStaticVar needs to be replicated as well !


                    First of all, let me address the PojoCacheable naming at the end.

                    I introduced that field annotation (@Replicatable) becuase I reckon there may be a case I don't want to replicate 1) any of the POJO static variables at all (this is happening most often); or 2) all of my static variables, e.g.,

                    org.jboss.cache.pojo.annotation.PojoCacheable
                    public class POJO
                    {
                     @org.jboss.cache.pojo.annotation.Replicatble
                     public static int someStaticVar;
                    
                     public static int anotherStaticVar; // this one won't get replicated.
                     ...
                    }
                    


                    So the annotation essentially allows user to replicate the static variable of her choice.

                    #2 Of course we need to support another static variable ! Ideally we adhere to the Java semantics


                    Sure, it will be supported. I meant in my originally post that we won't support a static variable of "aspectized" POJO type, e.g.,
                    org.jboss.cache.pojo.annotation.PojoCacheable
                    public class Foo
                    {
                    ...
                    }
                    
                    org.jboss.cache.pojo.annotation.PojoCacheable
                    public class POJO
                    {
                     @org.jboss.cache.pojo.annotation.Replicatble
                     public static Foo someStaticVar; // we cant support that someStaticVar is of type Foo of which is PojoCacheable.
                     ...
                    }
                    


                    Reason? Well, static variable is usually initialized failry early in the program lifecycle. So support of another POJO type to be managed by the PojoCache can be troublesome. I imagine mostly the static type to be primitive. Or am I assuming too much?

                    #3 Sure. Implementation issue correct ?

                    #4 Or lazy, whatever. Implementation issue again


                    Yes, implementation issues.

                    #5 Why ? we can have N someStaticVars per *cluster*...


                    Now I don't get you. If someStaticVars is replicated, then there can only be a someStaticVar per *cluster* (sure, different VM will have their own instances). I was proposing to allow inside each VM, only one PojoCache instance is allowed to have static variable replication. Elias' discussion is also focused on this area as well.

                    Finally, on the naming of @PojoCacheable instead of @Clustered or @Replicated. I have thought about that before. I think @Clustered or @Clusterable is not appropriate becuase we are talking about state replication only (i.e., no client side load balancing).

                    As for @Replicated, it is possible. But the expectation will be different. E.g., a user should not expect that once the Pojo is annotated and instantiated, then thing will happen automatically. That is, we are not using the API-less model; we still need to have api to *attach* the POJO. So @Replicated tag is a bit overloaded, IMO.




                    • 7. Re: static field replication in PojoCache
                      belaban

                       

                      "ben.wang@jboss.com" wrote:


                      I introduced that field annotation (@Replicatable) becuase I reckon there may be a case I don't want to replicate 1) any of the POJO static variables at all (this is happening most often); or 2) all of my static variables, e.g.,

                      org.jboss.cache.pojo.annotation.PojoCacheable
                      public class POJO
                      {
                       @org.jboss.cache.pojo.annotation.Replicatble
                       public static int someStaticVar;
                      
                       public static int anotherStaticVar; // this one won't get replicated.
                       ...
                      }
                      





                      I think this is not intuitive: @PojoCacheable replicates *all* variables, so static vars should be included.
                      You can exclude static vars using the transient keyword or @transient annotation.


                      #2 Of course we need to support another static variable ! Ideally we adhere to the Java semantics


                      Sure, it will be supported. I meant in my originally post that we won't support a static variable of "aspectized" POJO type, e.g.,
                      org.jboss.cache.pojo.annotation.PojoCacheable
                      public class Foo
                      {
                      ...
                      }
                      
                      org.jboss.cache.pojo.annotation.PojoCacheable
                      public class POJO
                      {
                       @org.jboss.cache.pojo.annotation.Replicatble
                       public static Foo someStaticVar; // we cant support that someStaticVar is of type Foo of which is PojoCacheable.
                       ...
                      }
                      


                      Reason? Well, static variable is usually initialized failry early in the program lifecycle. So support of another POJO type to be managed by the PojoCache can be troublesome. I imagine mostly the static type to be primitive. Or am I assuming too much?


                      Can we at least try before we give up ? :-) I don't (currently) see why static vars should only be of primitive types... So, okay, we can create those instances but only replicate them once we have been fully initialized.


                      #5 Why ? we can have N someStaticVars per *cluster*...


                      Now I don't get you. If someStaticVars is replicated, then there can only be a someStaticVar per *cluster* (sure, different VM will have their own instances). I was proposing to allow inside each VM, only one PojoCache instance is allowed to have static variable replication. Elias' discussion is also focused on this area as well.


                      Why should only 1 PojoCache be allowed to have static var replication inside the same VM ? This sounds like an arbitrary restriction...


                      Finally, on the naming of @PojoCacheable instead of @Clustered or @Replicated. I have thought about that before. I think @Clustered or @Clusterable is not appropriate becuase we are talking about state replication only (i.e., no client side load balancing).

                      As for @Replicated, it is possible. But the expectation will be different. E.g., a user should not expect that once the Pojo is annotated and instantiated, then thing will happen automatically. That is, we are not using the API-less model; we still need to have api to *attach* the POJO. So @Replicated tag is a bit overloaded, IMO.


                      Still much better than @PojoCacheable, which is horrible

                      • 8. Re: static field replication in PojoCache

                         

                        "bela@jboss.com" wrote:

                        I think this is not intuitive: @PojoCacheable replicates *all* variables, so static vars should be included.
                        You can exclude static vars using the transient keyword or @transient annotation.


                        But keep in mind that by default, we skip replicating static, final, and transient now. If we want to change the default to replicate static field, question is how often people want to replicate static field? If often, then yes, default is good. But otherwise, default may not be that good.

                        And what about final field default?


                        Why should only 1 PojoCache be allowed to have static var replication inside the same VM ? This sounds like an arbitrary restriction...


                        Yeah, agreed then. I am still thinking if there is a better way to support it other than explicit api.


                        Still much better than @PojoCacheable, which is horrible


                        I will create a new thread to discuss this then.

                        • 9. Re: static field replication in PojoCache
                          belaban



                          But keep in mind that by default, we skip replicating static, final, and transient now. If we want to change the default to replicate static field, question is how often people want to replicate static field? If often, then yes, default is good. But otherwise, default may not be that good.


                          By default we need to replicate static fields, don't replicate final and transient (or @transient) fields.



                          • 10. Re: static field replication in PojoCache
                            belaban

                             


                            Yeah, agreed then. I am still thinking if there is a better way to support it other than explicit api.


                            Yes, agreed. I don't see the need for this API.

                            • 11. Re: static field replication in PojoCache

                              OK, let me try to propose from step 1 again on a newer approach after collecting these feedback. Let's first list the example POJO though:

                              public class POJO
                              {
                               public static int someStaticVar;
                              
                               @Transient
                               private static int anotherStaticVar;
                              
                               ...
                              }
                              


                              1. static field replication is on by *default*. If a user wants to turn it off, he can annotate it with @Transient tag as in the above code snippet.

                              2. There will be no new API introduced. Instead, we will rely on the usual POJO attach/detach to trigger static field replication. E.g.,
                              ...
                              // First attach will trigger static field replication as well.
                              cache.attach("id", pojo);
                              ...
                              cache.someStaticVar = 20; // This will get replicated.
                              
                              // last attach will remove the static field.
                              cache.detach("id");
                              


                              2a. Again we will store the static variable under a special area, /__JBoss_Static__/.

                              2b. We will do reference counting to keep track of how many POJO there are associating it (such that we know when to remove the replicated static field).

                              I think this is much cleaner approach. What do you think?



                              • 12. Re: static field replication in PojoCache

                                BTW, the corresponding Jira is:
                                http://jira.jboss.com/jira/browse/JBCACHE-726

                                • 13. Re: static field replication in PojoCache
                                  belaban

                                  Absolutely, +1. This is in line with the rest of our semantics

                                  • 14. Re: static field replication in PojoCache
                                    manik

                                     


                                    Can we at least try before we give up ? :-) I don't (currently) see why static vars should only be of primitive types... So, okay, we can create those instances but only replicate them once we have been fully initialized.


                                    I agree that we should not just support static primitives. I can foresee many object models that will use static objects. And I don't see why this should be an issue anyway.



                                    1 2 Previous Next