[Logo] Terracotta Discussion Forums
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
[Expert]
using inherited protected fields in a sub class as a root.  XML
Forum Index -> Terracotta Platform
Author Message
alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

First , what am i trying to do ?

I want to cluster the fields of the concrete classes , all of which are derived from an abstract class. Currently the abstract class has some state info which would be great to cluster, but if it is possible to cluster the instances of the concrete class you could do the following :

Code:
 
 pseudo code :
 
 abstract class A
 {
    protected Object myLock = new Object();
 }
 
 class B extends A;
 
 class C extends C;
 
 


Then in the root defs define :

Code:
<root>
    <field> B.myLock </field>
 <root>
 
 <root>
    <field> C.myLock </field>
 <root>


Is this supported ? Else it appears all roots have to really be in a singleton and the plug'd into any reusable logic aka. make a runtime context or its fields a root, and that context object is then shared with multiple pojo's (set during some lifecycle management via a call to setContext(xxx)).
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

I think it should be fine - but not sure. It's easy to write a test to see which behavior you get...
[WWW]
alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

did do a quick test.

it didn't work. in the admin console, the root is not visible.

Alan.
asingh

neo

Joined: 02/05/2008 15:17:36
Messages: 1
Offline

If what you want at all is to share the state in the abstract class, you can just declare the myLock field in the abstract class as the root instead of using the concrete classes.
Code:
 <root>
    <field-name>A.myLock</field-name>
 </root>
 

The "myLock" field will be clustered and shared across all instances of B and C and across jvms.

Thanks,
Abhishek
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

Abishek,

Good point, I just assumed that the original intent was for the three separate subclasses to have different roots.
[WWW]
alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

Oh, i get that by defining it in the Abstract Class it will be shared by all 3. I dont' want that.

I want a nice way to define roots in an OO sense, without resorting to singletons for each class instance.

So,

"original intent was for the three separate subclasses to have different roots. "

is correct.

Alan.
ndolgov

neo

Joined: 09/12/2008 15:12:29
Messages: 1
Location: San Francisco, CA
Offline

tgautier wrote:
I think it should be fine - but not sure. It's easy to write a test to see which behavior you get... 


From what I can see the straightforward approach does not work but I am not sure what exactly is the limiting factor. To the best of my knowledge nowhere in documentation it is prohibited to cluster protected fields from a parent object. So it would be nice to know the official guidelines on it.

The use-case is simple:

class A {
protected Object F;
}

class B extends A {
}

<roots>
<root>
<field-name>B.F</field-name>
</root>
<roots>

And I would like to have the field F clustered as a root for multiple distributed instances of class B. What I see in admin console is that there are two clients connected to the server but no Roots. It used to work correctly when both A and B had their own private F fields. So my current guess is that clustering inherited fields does not work.

As a matter of fact, the idea was to independently cluster both classes but it sounds as if the following root structure:

<roots>
<root>
<field-name>A.F</field-name>
</root>
<root>
<field-name>B.F</field-name>
</root>
<roots>

would at best share the same state among all A and B instances. I am not awfully happy with this design and would not code it like that myself. Nevertheless, a clarification on what is actually supported in Terracotta in this respect would help.
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

would at best share the same state among all A and B instances. I am not awfully happy with this design and would not code it like that myself. Nevertheless, a clarification on what is actually supported in Terracotta in this respect would help. 


I would have to guess that it follows the Java conventions - that field isn't a part of B at all, it's a part of A (in other words, a root can only be declared on a class for a field that is in the set of fields returned from getDeclaredFields()).

I just wasn't sure if we did something that violates that constraint - it appears we don't. I don't even know why I thought it might be possible - we never violate Java principles like that.

I agree that this design is very bad. Having "different" fields F in B and C subclasses violates OOP programming priniciples, which is to say that B and C explicitly claim to "be an A", which is where the definition of F is, but now you're trying to make B and C "not be an A".

In this case, one should consider composition instead - B and C have an instance of A for reuse, but do not extend it. Then the instance in B and C can be different (and be a root) and OOP principles are solid.

In general, I don't like inheritance, it is over and misused quite often, when simple composition and delegation would suffice - and be better.

See Effective Java, and many blogs, for more on this topic.

[WWW]
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

ndolgov wrote:
So my current guess is that clustering inherited fields does not work. 


Just to clarify - a root can only be declared in the directly enclosing class - not a subclass.
[WWW]
jgalang

master

Joined: 05/24/2006 15:08:59
Messages: 54
Offline

Here's a thread tackling the same issue: http://forums.terracotta.org/forums/posts/list/15/1299.page

Bottom line, the answer to your question is: No.
Currently there is no way to make inherited fields to act as different roots.

Want to post to this forum? Please join the Terracotta community: >Sign up

alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

I get all the bit about composition with inheritance etc.


remember, the question is a contrived question to better understand the implications of using terracotta in making architecture and design questions.

Let me explain :

A lot of traditional OO models go out the door when you look at terracotta. Not saying its a bad product. In fact I am amazed at how well it makes doing difficult things easily. Really i am. I am a fan.

So, what was I HOPING FOR : when a root was defined on a superclass, subclasses (unless the root field is static in the base class) get a new root instance. ie. the definition of the root is inherited, not the instance of the root. Traditional use patterns in java focus on the classes, but now we have this metadata that sits beside any object model. But the metadata appears to be "static", and itself can't be inherited. My contrived question was in part based on a way more complex real world example (which is actually very common ).

What I am looking at (as I have this issue now) are design and reuse patterns for our developers. (I am also outside of a web container).

Now, if you look at terracotta, the use of ROOTS imposes a limitation on the design, because it effectively introduces a singleton within the class hierarchy. At the moment reuse of logic etc requires a lot of cut and paste, which over time will become a problem to maintain and duplicate effort in root def's and method locks or the use of lots of transients. Remember, some of this code can also has a life outside of terracotta.

So lets ask first,
"what we were trying to do and why are we trying to do it", within the limitations of the current version of the product :

With a TIM at the moment , you still basically declare a global singleton. What you can't do is say -> for an instance of this class X, create a new set of roots as described by some meta description of X.

In particular, say you have a service class (actually, we have a base service class that implements a generic master worker impl, where we do use composition to plug in our own routers and workers - this is how we customize for a given domain), but what I don't want is to have to cut and paste all the thread code, the shared queue's etc.

Now in a traditional java impl, i would say create an Abstract service (for us that makes sense), because that really is the easiest way to bundle a number of seperate modules (I think they call that composition ;-) ) in abstract way but the goal is actually more. Remember, in an oo world, those fields in a class only describe the definition of the field. What I was actually asking is there a way to cluster on the instance of that field.

But in Terracotta currently I have to cluster on the roots in the FINAL subclass, which effectively makes the final super class a global singleton. What I can't do is make the instance of those variables a root. Which even with composition is actually limiting the ability to build better TIM's. So , in many ways the use of SUPER STATIC class, without the ability to define "meta roots" (call them what you will) can very easily turn a complex application into a) a function model (if you are not careful) or b) a huge number of duplicate root, lock and include statements in the tconfig.xml, which over the life cycle of an application will add to its maintainability.

If there is another way to implement this reuse then thats a different story. At the moment the best practice for reuse is to cut and paste (which has an annoying habit of cut and pasting bugs... and this is multi threaded code also). So i am looking for ways to help manage that.

So in summary, at the moment the best method for reuse seems to be a singleton factory that manages shared "instances" (ie - topology manager in the forge master worker ) and then the created shared object from the global factory is assigned to the runtime instance of our logic.
tgautier

seraphim

Joined: 06/05/2006 12:19:26
Messages: 1781
Offline

Well, I guess I'd have to say that I don't think I agree with you in this particular instance. What you are trying to do is simply not OOP, and it's not supported by the Java bytecode. The instruction that is generated - not only for the subclasses, but any class in the package that has protected access to the field will modify A.F not B.F and C.F.

You've said it yourself - the effect of a root is to make the field static - so if A.F being static doesn't work, you need to choose another field to be a root, or create a special one, and put A, B, and C instances in that root, leaving A, B and C to work as you wish.

But I will say that I have noticed that there are certain commonalities to using/making roots. It's not always an easy choice, but after using the product for a long time, and observing others use it, I am trying to formulate those commonalities into concrete design patterns.

I have been noticing that while it's possible to "encapsulate" the notion of clustered state entirely within a class - it's best to externalize it explicitly. The only reasonable way to encapsulate the clustered state internally within a single class is to essentially "know" that the class will be clustered when writing the code. This is in essence I think what you are saying about this contrived example.

Better is to create some external store of the state, as you mention, the Topology (which is exactly why I created that class, among other reasons). Then all the classes that are held in the root don't have to "know" about being clustered or not, so this knowledge is encapsulated within that particular class, and the rest of the implementation doesn't know or care about it.

If you think about it - this all makes a fair bit of sense - the root is the place where something strange happens. It seems fair that a good design pattern would acknowledge this and recommend to encapsulate that knowledge, thus make sure that the root creation/management is a separate concern from the rest of the code.
[WWW]
alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

so global factory pattern is option 1.

But... lets stand back a bit from the low level implementation. And ask .. If I was user, what would be better.

Say I want to write 3 services, but I want to use the master worker pattern in each service.

a) start new project.
b) include TIM
c) create instance of abstract TIM class (why abstract -> I like it because it can't have a concrete instance....)
d) automatically without any config you have a running instance of a clustered object/module.

up and and going in 5 min.

versus

Service 1 -> code, define all member fields as needed as root etc.
Service 2 -> copy code from service 1, repeat again.
Service 3 -> repeat again -> both in code and tcconfig.

oh... I have a basic logic bug... go to each duplicate copy of the code and repeat.

up and going in a little while longer....

Which is sort of how it is reused today.

I pick on abstract classes because you can't directly create them, so it would make a nice way to define "abstract roots". now impl....that might be a bit of different issue....

alanww35

journeyman

Joined: 08/21/2008 11:11:05
Messages: 22
Offline

so at this stage it seems to be

a) global factory for shared objects
b) "shell" classes for methods (don't know a better name) (local state and logic).
c) a+b come together in reuse.

In particular I am thinking on how to package code in TIM's (I actually have some cool code that would be nice to package and share - but you might not like it 100% -> it uses a modified Hungarian notation - sorry 15+ years of x number of languages, 4 commercial software systems (some big ones) - I find it just works in cutting down bugs ;-) it really does ).

Side note -> i like the way locking works on inheritance.
 
Forum Index -> Terracotta Platform
Go to:   
Powered by JForum 2.1.7 © JForum Team