You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@geronimo.apache.org by Greg Wilkins <gr...@mortbay.com> on 2006/07/14 10:47:11 UTC

Cluster API proposal?


This is my idea of how we could morph the currently proposed session APIs
into a cluster API.

I have created a spot for Cluster meta data - but I have not filled it out much.

The key difference is that the state Map is now indexed by session ID and context ID.
This allows the state for different contexts within the same session to be on different
nodes (this is a real requirement) and also means that locking is at context rather
than meta session level.  Note that some implementations may not fully support 
this and may just do sessionId+contextId behind the scenes and colocate all context
states for the same session (and move them as one).

I have also added an async aspect to the API for potentially long operations
such as moving state about the place - again this can be optionally supported.

Also I support the idea of multiple Nodes per server (really useful for testing
and heterogeneous clusters).



// The top level Cluster API - this was the Locator... but let's call a spade a spade.

interface Cluster
{
     // methods to get/set meta data about the cluster
     // these signatures here are just a guess... but you get the idea.
     int getMaxNodes();
     Set<Node> getKnownNodes();
     void setKnownNodes(Set<Node> nodes);
     Node getLocalNode();

     // Access sessions in cluster.  
     MetaSession getMetaSession(String clientID);
     Session createMetaSession(String sessionId);

}


// Node API
// was Server - but may have multiple Nodes per server
interface Node
{
    String getName();    
    String[] getAddresses(String protocol);    
    void setAddresses(String string, String[] strings);    
    boolean isLocalServer();
    boolean isActive();

    int getPort(String protocol);  // one way to handle the multi nodes per server
    int getPortOffset();           // or this one (add to standard port)
}


// Meta Session - was SessionLocation
interface MetaSession
{
    String getSessionId();
    void invalidate();

    void addEventListener(MetaSessionListener listener);
    void removeEventListener(MetaSessionListener listener);

    // State API has map per context ID , where a context
    // ID might be "web:/context" or "ejb:" or random
    boolean isStateLocal(String contextId);


    Map getState(String contextId);          // implies a move local!
    void getStateAsync(Object key, String contextId);  // async version 

    Map createState(String contextId);
    void releaseState(String contextId); // don't lock whole meta session!
    void invalidate(String contextId);

    // Locaton / Policy API.
    Node getNode(String contextId); 
    Node getExecutionNode(String contextId); 
    void getExecutionNodeAsync(Object key, String contextId);    


    // Don't know if these are too HTTP specific... but we need them 
    void setPassivationTimeout(long ms, String contextId);
    void setInvalidationTimeout(long ms, String contextId);
}


interface MetaSessionListener
{
    // callbacks to allow session manager to inspect contents for 
    // tier specific handling (eg servlet listeners etc.)
    void activateState(String sessionId, String contextId, Map state);
    void passivateState(String sessionId, String contextId, Map state);
    void invalidateState(String sessionId, String contextId, Map state);

    // callbacks for async operations
    void gotState(Object key, String sessionId, String contextId, Map state);
    void executionNode(Object key, String sessionId, String contextId, Node location);

}


Re: Cluster API proposal?

Posted by Greg Wilkins <gr...@mortbay.com>.
Dain Sundstrom wrote:
> I think we are starting to agree. 

agreed :-)

I think that a Cluster interface with the stateless methods as proposed by filip would be
good, plus a SessionManager interface with the stateful stuff.

Actually, I don't like SessionManager as a name... maybe StateManager?

If the same bean implements both APIs, great!  But I see no need for 
a common root.

I am still keen on a context ID, but I'll advocate that in a separate email.

cheers




Re: Cluster API proposal?

Posted by Dain Sundstrom <da...@iq80.com>.
I think we are starting to agree.  I see the session manager as a  
high level component that *can* be implemented on top of a cluster or  
just be a local hash map.  The idea was to create an abstraction such  
that, the people writing clustering code can easily plugin into  
geronimo services that have session data (which is about the only  
pice of cluster data that we have right now).

As for low level Clustering apis, I don't have much of a preference  
unless I have to write to them, and the stuff I'm working on can be  
completely satisfied by the session api.

-dain

On Jul 14, 2006, at 6:41 AM, Filip Hanik - Dev Lists wrote:

> Cool, thanks for posting this.
> While I do believe everything in this API is very useful, I see it  
> as an extension to the one I created.
> My API is only about the cluster, and its meta data, while the API  
> below is very session oriented.
>
> In a cluster without state replication, most of the methods below  
> would return null or throw UnsupportedOperationException, hence it  
> would make it harder to implement, and less useful.
> The API below is essentially meta data about session state. I  
> personally consider this an extension to the Cluster API, or a  
> higher level component, and bada bim, we are back at SessionAPI :),  
> our favorite topics.
>
> Does this make sense? I was looking for the lowest common  
> denominator, for what a "cluster" is, essentially, nothing but a  
> group of VMs.
> So what I try to do, is that the group wont be forced to expose  
> session state, cause if there is no state replication, you couldn't  
> implement that API.
>
> Because I haven't thought much of the session API, as I do consider  
> that a higher level component, I haven't yet though of a good way,  
> if there is one, how that would sit on top of a cluster API. But I  
> do believe they shouldn't be morphed together, instead of the  
> SessionAPI must know about nodes and clusters, it would get that  
> from the cluster api, <ot>although i personally believe the session  
> api should only know about sessions and nothing else, but that is  
> why I am staying out of that topic :)</ot>
>
> Filip
>
>
> Greg Wilkins wrote:
>> This is my idea of how we could morph the currently proposed  
>> session APIs
>> into a cluster API
>>   I have created a spot for Cluster meta data - but I have not  
>> filled it out much.
>>
>> The key difference is that the state Map is now indexed by session  
>> ID and context ID.
>> This allows the state for different contexts within the same  
>> session to be on different
>> nodes (this is a real requirement) and also means that locking is  
>> at context rather
>> than meta session level.  Note that some implementations may not  
>> fully support this and may just do sessionId+contextId behind the  
>> scenes and colocate all context
>> states for the same session (and move them as one).
>> I have also added an async aspect to the API for potentially long  
>> operations
>> such as moving state about the place - again this can be  
>> optionally supported.
>>
>> Also I support the idea of multiple Nodes per server (really  
>> useful for testing
>> and heterogeneous clusters).
>>
>>
>>
>> // The top level Cluster API - this was the Locator... but let's  
>> call a spade a spade.
>>
>> interface Cluster
>> {
>>      // methods to get/set meta data about the cluster
>>      // these signatures here are just a guess... but you get the  
>> idea.
>>      int getMaxNodes();
>>      Set<Node> getKnownNodes();
>>      void setKnownNodes(Set<Node> nodes);
>>      Node getLocalNode();
>>
>>      // Access sessions in cluster.       MetaSession  
>> getMetaSession(String clientID);
>>      Session createMetaSession(String sessionId);
>>
>> }
>>
>>
>> // Node API
>> // was Server - but may have multiple Nodes per server
>> interface Node
>> {
>>     String getName();        String[] getAddresses(String  
>> protocol);        void setAddresses(String string, String[]  
>> strings);        boolean isLocalServer();
>>     boolean isActive();
>>
>>     int getPort(String protocol);  // one way to handle the multi  
>> nodes per server
>>     int getPortOffset();           // or this one (add to standard  
>> port)
>> }
>>
>> // Meta Session - was SessionLocation
>> interface MetaSession
>> {
>>     String getSessionId();
>>     void invalidate();
>>
>>     void addEventListener(MetaSessionListener listener);
>>     void removeEventListener(MetaSessionListener listener);
>>
>>     // State API has map per context ID , where a context
>>     // ID might be "web:/context" or "ejb:" or random
>>     boolean isStateLocal(String contextId);
>>
>>
>>     Map getState(String contextId);          // implies a move local!
>>     void getStateAsync(Object key, String contextId);  // async  
>> version
>>     Map createState(String contextId);
>>     void releaseState(String contextId); // don't lock whole meta  
>> session!
>>     void invalidate(String contextId);
>>
>>     // Locaton / Policy API.
>>     Node getNode(String contextId);     Node getExecutionNode 
>> (String contextId);     void getExecutionNodeAsync(Object key,  
>> String contextId);
>>
>>     // Don't know if these are too HTTP specific... but we need  
>> them     void setPassivationTimeout(long ms, String contextId);
>>     void setInvalidationTimeout(long ms, String contextId);
>> }
>>
>>
>> interface MetaSessionListener
>> {
>>     // callbacks to allow session manager to inspect contents  
>> for     // tier specific handling (eg servlet listeners etc.)
>>     void activateState(String sessionId, String contextId, Map  
>> state);
>>     void passivateState(String sessionId, String contextId, Map  
>> state);
>>     void invalidateState(String sessionId, String contextId, Map  
>> state);
>>
>>     // callbacks for async operations
>>     void gotState(Object key, String sessionId, String contextId,  
>> Map state);
>>     void executionNode(Object key, String sessionId, String  
>> contextId, Node location);
>>
>> }
>>
>>
>>


Re: Cluster API proposal?

Posted by Filip Hanik - Dev Lists <de...@hanik.com>.
Cool, thanks for posting this.
While I do believe everything in this API is very useful, I see it as an 
extension to the one I created.
My API is only about the cluster, and its meta data, while the API below 
is very session oriented.

In a cluster without state replication, most of the methods below would 
return null or throw UnsupportedOperationException, hence it would make 
it harder to implement, and less useful.
The API below is essentially meta data about session state. I personally 
consider this an extension to the Cluster API, or a higher level 
component, and bada bim, we are back at SessionAPI :), our favorite topics.

Does this make sense? I was looking for the lowest common denominator, 
for what a "cluster" is, essentially, nothing but a group of VMs.
So what I try to do, is that the group wont be forced to expose session 
state, cause if there is no state replication, you couldn't implement 
that API.

Because I haven't thought much of the session API, as I do consider that 
a higher level component, I haven't yet though of a good way, if there 
is one, how that would sit on top of a cluster API. But I do believe 
they shouldn't be morphed together, instead of the SessionAPI must know 
about nodes and clusters, it would get that from the cluster api, 
<ot>although i personally believe the session api should only know about 
sessions and nothing else, but that is why I am staying out of that 
topic :)</ot>

Filip


Greg Wilkins wrote:
> This is my idea of how we could morph the currently proposed session APIs
> into a cluster API
>   
> I have created a spot for Cluster meta data - but I have not filled it out much.
>
> The key difference is that the state Map is now indexed by session ID and context ID.
> This allows the state for different contexts within the same session to be on different
> nodes (this is a real requirement) and also means that locking is at context rather
> than meta session level.  Note that some implementations may not fully support 
> this and may just do sessionId+contextId behind the scenes and colocate all context
> states for the same session (and move them as one).
> I have also added an async aspect to the API for potentially long operations
> such as moving state about the place - again this can be optionally supported.
>
> Also I support the idea of multiple Nodes per server (really useful for testing
> and heterogeneous clusters).
>
>
>
> // The top level Cluster API - this was the Locator... but let's call a spade a spade.
>
> interface Cluster
> {
>      // methods to get/set meta data about the cluster
>      // these signatures here are just a guess... but you get the idea.
>      int getMaxNodes();
>      Set<Node> getKnownNodes();
>      void setKnownNodes(Set<Node> nodes);
>      Node getLocalNode();
>
>      // Access sessions in cluster.  
>      MetaSession getMetaSession(String clientID);
>      Session createMetaSession(String sessionId);
>
> }
>
>
> // Node API
> // was Server - but may have multiple Nodes per server
> interface Node
> {
>     String getName();    
>     String[] getAddresses(String protocol);    
>     void setAddresses(String string, String[] strings);    
>     boolean isLocalServer();
>     boolean isActive();
>
>     int getPort(String protocol);  // one way to handle the multi nodes per server
>     int getPortOffset();           // or this one (add to standard port)
> }
>
> // Meta Session - was SessionLocation
> interface MetaSession
> {
>     String getSessionId();
>     void invalidate();
>
>     void addEventListener(MetaSessionListener listener);
>     void removeEventListener(MetaSessionListener listener);
>
>     // State API has map per context ID , where a context
>     // ID might be "web:/context" or "ejb:" or random
>     boolean isStateLocal(String contextId);
>
>
>     Map getState(String contextId);          // implies a move local!
>     void getStateAsync(Object key, String contextId);  // async version 
>
>     Map createState(String contextId);
>     void releaseState(String contextId); // don't lock whole meta session!
>     void invalidate(String contextId);
>
>     // Locaton / Policy API.
>     Node getNode(String contextId); 
>     Node getExecutionNode(String contextId); 
>     void getExecutionNodeAsync(Object key, String contextId);    
>
>
>     // Don't know if these are too HTTP specific... but we need them 
>     void setPassivationTimeout(long ms, String contextId);
>     void setInvalidationTimeout(long ms, String contextId);
> }
>
>
> interface MetaSessionListener
> {
>     // callbacks to allow session manager to inspect contents for 
>     // tier specific handling (eg servlet listeners etc.)
>     void activateState(String sessionId, String contextId, Map state);
>     void passivateState(String sessionId, String contextId, Map state);
>     void invalidateState(String sessionId, String contextId, Map state);
>
>     // callbacks for async operations
>     void gotState(Object key, String sessionId, String contextId, Map state);
>     void executionNode(Object key, String sessionId, String contextId, Node location);
>
> }
>
>
>   


Re: Cluster API proposal?

Posted by Greg Wilkins <gr...@mortbay.com>.
Dain Sundstrom wrote:
> On Jul 14, 2006, at 1:47 AM, Greg Wilkins wrote:
> 
>> This is my idea of how we could morph the currently proposed session APIs
>> into a cluster API.
>>
>> I have created a spot for Cluster meta data - but I have not filled it
>> out much.
>>
>> The key difference is that the state Map is now indexed by session ID
>> and context ID.
>> This allows the state for different contexts within the same session
>> to be on different
>> nodes (this is a real requirement)
> 
> I think I missed some of the discussion.  Why is this a requirement?  I
> know some deployments like to split applications into multiple tiers,
> but why would the servlet or ejb containers need to know about that?


I can see many reasons for having a session be a map of maps rather
than just a flat map:

The actual thing we are modelling is a map of maps. We know that 
beneath a session ID there can be multiple non-intersecting state 
spaces for EJBs, webcontexts, POJOs, whatever.    If we know this
is the model why not model it in out data structure?


If the underlying implementation is just a single flat space, then
it is trivial to store a map of maps into a single map by adding name
prefixes.

But if the underlying implementation is capable of modelling a map
of maps, then we avoid the inefficiencies of adding prefixes for 
every lookup, excessive iteration, coarse locking etc.

Conversely, if our API is a flat space - all the state for 
all contexts must be collocated and a request to one context will
lock the entire state.  Note that with mashups and portlets, you can
expect that multiple contexts for the same session could be accessed
in parallel.

Heterogeneous clusters are needed.  As well as clusters that are 
partitioned by tier (which if often a bad idea), we need to support
clusters partitioned by context (some web contexts to a subset of 
nodes and others to another subset).  This includes some single sign-on 
solutions which are actually multiple clusters sharing a session ID space.

If a session state space is a single flat space, then it will be very 
difficult (if not impossible) to support heterogeneous clusters as 
the entire state for a session ID will need to be co-located.

It may also be that individual context will need different
locking strategies and their individual context maps can be
wrapped accordingly.  For example, some contexts may release
their state map when a request has completed, while others
may release after every setAttribute call (because they may be
part of a long held Ajax/Comet request!)

So I see a map of maps gives us much better targeted semantics 
with little extra complexity.

cheers










 


Re: Cluster API proposal?

Posted by Dain Sundstrom <da...@iq80.com>.
On Jul 14, 2006, at 1:47 AM, Greg Wilkins wrote:

> This is my idea of how we could morph the currently proposed  
> session APIs
> into a cluster API.
>
> I have created a spot for Cluster meta data - but I have not filled  
> it out much.
>
> The key difference is that the state Map is now indexed by session  
> ID and context ID.
> This allows the state for different contexts within the same  
> session to be on different
> nodes (this is a real requirement)

I think I missed some of the discussion.  Why is this a requirement?   
I know some deployments like to split applications into multiple  
tiers, but why would the servlet or ejb containers need to know about  
that?

> and also means that locking is at context rather
> than meta session level.  Note that some implementations may not  
> fully support
> this and may just do sessionId+contextId behind the scenes and  
> colocate all context
> states for the same session (and move them as one).

If we assume we are working in an IoC environment, I don't see why  
the api would need to explicitly call out support for a context.   
Lets say Jetty has a setter for SessionManager, if you want to have a  
private context for your jetty data, you can simply have the IoC  
layer inject a wrapped version of SessionManager that does the string  
append, or if your clustering framework supports the concept of a  
context directly, the IoC layer could inject  
fooCluster.getPrivateSessionContext(contextId).

This is what I like about the session API.  It only contains the apis  
needed for someone to get their session data.  All complex deployment  
decisions or configuration can be pushed to the IoC layer.

I have specific comments about the apis below.

-dain

> // The top level Cluster API - this was the Locator... but let's  
> call a spade a spade.
>
> interface Cluster
> {
>      // methods to get/set meta data about the cluster
>      // these signatures here are just a guess... but you get the  
> idea.
>      int getMaxNodes();
>      Set<Node> getKnownNodes();
>      void setKnownNodes(Set<Node> nodes);
>      Node getLocalNode();
>
>      // Access sessions in cluster.
>      MetaSession getMetaSession(String clientID);
>      Session createMetaSession(String sessionId);
> }

I'd prefer we don't call it cluster as it could then concievely  
contain anything.  The job of this interface is to manage session and  
I think we should call it a SessionManager.

> // Node API
> // was Server - but may have multiple Nodes per server
> interface Node
> {
>     String getName();
>     String[] getAddresses(String protocol);
>     void setAddresses(String string, String[] strings);
>     boolean isLocalServer();
>     boolean isActive();
>
>     int getPort(String protocol);  // one way to handle the multi  
> nodes per server
>     int getPortOffset();           // or this one (add to standard  
> port)
> }

Calling it a Node is cool with me.

I'd drop the port stuff.  Ports imply IP and protocols could be P2P  
and wouldn't have a port.  When James and I wrote this, we expected  
addresses to contain a URI, but didn't want to force java.net.URI on  
everyone, so we went with String.

> // Meta Session - was SessionLocation
> interface MetaSession
> {
>     String getSessionId();
>     void invalidate();
>
>     void addEventListener(MetaSessionListener listener);
>     void removeEventListener(MetaSessionListener listener);
>
>     // State API has map per context ID , where a context
>     // ID might be "web:/context" or "ejb:" or random
>     boolean isStateLocal(String contextId);
>
>
>     Map getState(String contextId);          // implies a move local!
>     void getStateAsync(Object key, String contextId);  // async  
> version
>
>     Map createState(String contextId);
>     void releaseState(String contextId); // don't lock whole meta  
> session!
>     void invalidate(String contextId);
>
>     // Locaton / Policy API.
>     Node getNode(String contextId);
>     Node getExecutionNode(String contextId);
>     void getExecutionNodeAsync(Object key, String contextId);
>
>
>     // Don't know if these are too HTTP specific... but we need them
>     void setPassivationTimeout(long ms, String contextId);
>     void setInvalidationTimeout(long ms, String contextId);
> }

As I mentioned above, I don't like the context stuff, but the rest is  
good.

I think we should drop the async method until we have some  
implementations.  Specially, I think it will need an optional  
listener parameter so you can be notified when the transfer is complete.

I think the passivation methods are good general purpose items.  Do  
we need a last modified, or last accessed items also?

> interface MetaSessionListener
> {
>     // callbacks to allow session manager to inspect contents for
>     // tier specific handling (eg servlet listeners etc.)
>     void activateState(String sessionId, String contextId, Map state);
>     void passivateState(String sessionId, String contextId, Map  
> state);
>     void invalidateState(String sessionId, String contextId, Map  
> state);
>
>     // callbacks for async operations
>     void gotState(Object key, String sessionId, String contextId,  
> Map state);
>     void executionNode(Object key, String sessionId, String  
> contextId, Node location);
>
> }

I don't think we need (or want) the async listener methods part of  
this interface.  I think we need a separate one if we add the method.