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.