| Method from org.jboss.ha.framework.server.ClusterPartition Detail: |
protected void bind(String jndiName,
Object who,
Class<?> classType,
Context ctx) throws Exception {
// Ah ! This service isn't serializable, so we use a helper class
//
NonSerializableFactory.bind(jndiName, who);
Name n = ctx.getNameParser("").parse(jndiName);
while (n.size () > 1)
{
String ctxName = n.get (0);
try
{
ctx = (Context)ctx.lookup (ctxName);
}
catch (NameNotFoundException e)
{
this.log.debug ("creating Subcontext " + ctxName);
ctx = ctx.createSubcontext (ctxName);
}
n = n.getSuffix (1);
}
// The helper class NonSerializableFactory uses address type nns, we go on to
// use the helper class to bind the service object in JNDI
//
StringRefAddr addr = new StringRefAddr("nns", jndiName);
Reference ref = new Reference(classType.getName (), addr, NonSerializableFactory.class.getName (), null);
ctx.rebind (n.get (0), ref);
}
Helper method that binds the partition in the JNDI tree. |
public void block() {
this.flushBlockGate.close();
this.log.debug("Block processed at " + this.me);
}
|
public void callAsyncMethodOnNode(String serviceName,
String methodName,
Object[] args,
Class[] types,
long methodTimeout,
ClusterNode targetNode) throws Throwable {
if (!(targetNode instanceof ClusterNodeImpl))
{
throw new IllegalArgumentException("targetNode " + targetNode + " is not an instance of " +
ClusterNodeImpl.class + " -- only targetNodes provided by this HAPartition should be used");
}
boolean trace = this.log.isTraceEnabled();
MethodCall m = new MethodCall(serviceName + "." + methodName, args, types);
if( trace )
{
this.log.trace("callAsyncMethodOnNode( objName="+serviceName
+", methodName="+methodName);
}
this.dispatcher.callRemoteMethod(((ClusterNodeImpl)targetNode).getOriginalJGAddress(), m, GroupRequest.GET_NONE, methodTimeout);
}
Calls method on target node only. |
public void callAsynchMethodOnCluster(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf) throws Exception {
boolean trace = this.log.isTraceEnabled();
MethodCall m = new MethodCall(objName + "." + methodName, args, types);
if(this.channel.flushSupported())
{
this.flushBlockGate.await(this.getStateTransferTimeout());
}
if (excludeSelf)
{
if( trace )
{
this.log.trace("callAsynchMethodOnCluster(true), objName="+objName
+", methodName="+methodName+", members="+this.jgotherMembers);
}
this.dispatcher.callRemoteMethods(this.jgotherMembers, m, GroupRequest.GET_NONE, this.getMethodCallTimeout());
}
else
{
if( trace )
{
this.log.trace("callAsynchMethodOnCluster(false), objName="+objName
+", methodName="+methodName+", members="+this.members);
}
this.dispatcher.callRemoteMethods(null, m, GroupRequest.GET_NONE, this.getMethodCallTimeout());
}
}
This function is an abstraction of RpcDispatcher for asynchronous messages |
public ArrayList callMethodOnCluster(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf) throws Exception {
return this.callMethodOnCluster(objName, methodName, args, types, excludeSelf, null);
}
This function is an abstraction of RpcDispatcher. |
public ArrayList callMethodOnCluster(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf,
ResponseFilter filter) throws Exception {
return this.callMethodOnCluster(objName, methodName, args, types, excludeSelf, this.getMethodCallTimeout(), filter);
}
|
public ArrayList callMethodOnCluster(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf,
long methodTimeout,
ResponseFilter filter) throws Exception {
RspList rsp = null;
boolean trace = this.log.isTraceEnabled();
MethodCall m = new MethodCall(objName + "." + methodName, args, types);
RspFilterAdapter rspFilter = filter == null ? null : new RspFilterAdapter(filter);
if(this.channel.flushSupported())
{
this.flushBlockGate.await(this.getStateTransferTimeout());
}
if (excludeSelf)
{
if( trace )
{
this.log.trace("callMethodOnCluster(true), objName="+objName
+", methodName="+methodName+", members="+this.jgotherMembers);
}
rsp = this.dispatcher.callRemoteMethods(this.jgotherMembers, m, GroupRequest.GET_ALL, methodTimeout, false, false, rspFilter);
}
else
{
if( trace )
{
this.log.trace("callMethodOnCluster(false), objName="+objName
+", methodName="+methodName+", members="+this.members);
}
rsp = this.dispatcher.callRemoteMethods(null, m, GroupRequest.GET_ALL, methodTimeout, false, false, rspFilter);
}
return this.processResponseList(rsp, trace);
}
|
public ArrayList callMethodOnCoordinatorNode(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf) throws Exception {
return this.callMethodOnCoordinatorNode(objName,methodName,args,types,excludeSelf, this.getMethodCallTimeout());
}
Calls method on Cluster coordinator node only. The cluster coordinator node is the first node to join the
cluster.
and is replaced |
public ArrayList callMethodOnCoordinatorNode(String objName,
String methodName,
Object[] args,
Class[] types,
boolean excludeSelf,
long methodTimeout) throws Exception {
boolean trace = this.log.isTraceEnabled();
MethodCall m = new MethodCall(objName + "." + methodName, args, types);
if( trace )
{
this.log.trace("callMethodOnCoordinatorNode(false), objName="+objName
+", methodName="+methodName);
}
// the first cluster view member is the coordinator
Vector< Address > coordinatorOnly = new Vector< Address >();
// If we are the coordinator, only call ourself if 'excludeSelf' is false
if (false == this.isCurrentNodeCoordinator () ||
false == excludeSelf)
{
coordinatorOnly.addElement(this.jgmembers.elementAt(0));
}
RspList rsp = this.dispatcher.callRemoteMethods(coordinatorOnly, m, GroupRequest.GET_ALL, methodTimeout);
return this.processResponseList(rsp, trace);
}
Calls method on Cluster coordinator node only. The cluster coordinator node is the first node to join the
cluster.
and is replaced |
public Object callMethodOnNode(String serviceName,
String methodName,
Object[] args,
Class[] types,
long methodTimeout,
ClusterNode targetNode) throws Throwable {
if (!(targetNode instanceof ClusterNodeImpl))
{
throw new IllegalArgumentException("targetNode " + targetNode + " is not an instance of " +
ClusterNodeImpl.class + " -- only targetNodes provided by this HAPartition should be used");
}
boolean trace = this.log.isTraceEnabled();
MethodCall m = new MethodCall(serviceName + "." + methodName, args, types);
if( trace )
{
this.log.trace("callMethodOnNode( objName="+serviceName
+", methodName="+methodName);
}
Object rc = this.dispatcher.callRemoteMethod(((ClusterNodeImpl)targetNode).getOriginalJGAddress(), m, GroupRequest.GET_FIRST, methodTimeout);
if (rc != null)
{
Object item = rc;
if (item instanceof Rsp)
{
Rsp response = (Rsp) item;
// Only include received responses
boolean wasReceived = response.wasReceived();
if( wasReceived == true )
{
item = response.getValue();
if (!(item instanceof NoHandlerForRPC))
{
rc = item;
}
}
else if( trace )
{
this.log.trace("Ignoring non-received response: "+response);
}
}
else
{
if (!(item instanceof NoHandlerForRPC))
{
rc = item;
}
else if( trace )
{
this.log.trace("Ignoring NoHandlerForRPC");
}
}
}
return rc;
}
Calls method synchrounously on target node only. |
protected void createService() throws Exception {
if (this.replicantManager == null)
{
this.replicantManager = new DistributedReplicantManagerImpl(this);
}
// registerDRM();
this.setupLoggers(this.getPartitionName());
this.replicantManager.createService();
if (this.distributedState instanceof ManagedDistributedState)
{
((ManagedDistributedState) this.distributedState).createService();
}
// Create the asynchronous handler for view changes
this.asynchHandler = new AsynchEventHandler(this, "AsynchViewChangeHandler");
// Add a well-known MC alias that other beans can depend on
addCanonicalAlias();
this.log.debug("done initializing partition");
}
|
protected void destroyService() throws Exception {
this.log.debug("Destroying HAPartition: " + this.getPartitionName());
removeCanonicalAlias();
if (this.distributedState instanceof ManagedDistributedState)
{
((ManagedDistributedState) this.distributedState).destroyService();
}
this.replicantManager.destroyService();
// unregisterDRM();
try
{
if (this.channel != null && this.channel.isOpen())
{
this.channel.close();
}
}
catch (Exception e)
{
this.log.error("Closing channel failed", e);
}
this.log.info("Partition " + this.getPartitionName() + " destroyed.");
}
|
protected void fetchState() throws Exception {
this.log.info("Fetching serviceState (will wait for " + this.getStateTransferTimeout() +
" milliseconds):");
long start, stop;
this.isStateSet = false;
start = System.currentTimeMillis();
boolean rc = this.channel.getState(null, this.getStateTransferTimeout());
if (rc)
{
synchronized (this.channelLock)
{
while (!this.isStateSet)
{
if (this.setStateException != null)
{
throw this.setStateException;
}
try
{
this.channelLock.wait();
}
catch (InterruptedException iex)
{
}
}
}
stop = System.currentTimeMillis();
this.log.info("serviceState was retrieved successfully (in " + (stop - start) + " milliseconds)");
}
else
{
// No one provided us with serviceState.
// We need to find out if we are the coordinator, so we must
// block until viewAccepted() is called at least once
synchronized (this.members)
{
while (this.members.size() == 0)
{
this.log.debug("waiting on viewAccepted()");
try
{
this.members.wait();
}
catch (InterruptedException iex)
{
}
}
}
if (this.isCurrentNodeCoordinator())
{
this.log.info("State could not be retrieved (we are the first member in group)");
}
else
{
throw new IllegalStateException("Initial serviceState transfer failed: " +
"Channel.getState() returned false");
}
}
}
|
public boolean getAllowSynchronousMembershipNotifications() {
return this.allowSyncListeners;
}
|
public boolean getBindIntoJndi() {
return this.bindIntoJndi;
}
|
public String getCacheConfigName() {
return this.cacheConfigName;
}
|
public HAPartitionCacheHandler getCacheHandler() {
return this.cacheHandler;
}
|
public ChannelFactory getChannelFactory() {
return this.channelFactory;
}
|
public String getChannelStackName() {
return this.stackName;
}
|
public ClusterNode getClusterNode() {
return this.me;
}
|
public ClusterNode[] getClusterNodes() {
synchronized (this.members)
{
return this.members.toArray(new ClusterNode[this.members.size()]);
}
}
|
public Vector<String> getCurrentView() {
Vector< String > result = new Vector< String >(this.members.size());
for (ClusterNode member: this.members)
{
result.add(member.getName());
}
return result;
}
|
public long getCurrentViewId() {
return this.currentViewId;
}
|
protected Vector<ClusterNode> getDeadMembers(Vector<ClusterNode> oldMembers,
Vector<ClusterNode> newMembers) {
if(oldMembers == null)
{
oldMembers=new Vector< ClusterNode >();
}
if(newMembers == null)
{
newMembers=new Vector< ClusterNode >();
}
Vector< ClusterNode > dead=(Vector< ClusterNode >)oldMembers.clone();
dead.removeAll(newMembers);
this.log.debug("dead members: " + dead);
return dead;
}
Helper method that returns a vector of dead members from two input vectors: new and old vectors of two views.
Dead members are old - new members. |
public boolean getDeadlockDetection() {
return false;
} Deprecated! will - be removed in next major release
Deprecated; always returns false. |
public DistributedReplicantManager getDistributedReplicantManager() {
return this.replicantManager;
}
|
public DistributedReplicantManagerImpl getDistributedReplicantManagerImpl() {
return this.replicantManager;
}
|
public DistributedState getDistributedStateService() {
return this.distributedState;
}
|
public HAPartition getHAPartition() {
return this;
}
|
public synchronized HAPartitionDependencyCreator getHaPartitionDependencyCreator() {
if (haPartitionDependencyCreator == null)
{
haPartitionDependencyCreator = DefaultHAPartitionDependencyCreator.INSTANCE;
}
return haPartitionDependencyCreator;
}
|
public String getJGroupsVersion() {
return Version.description + "( " + Version.cvs + ")";
}
|
public long getMethodCallTimeout() {
return this.method_call_timeout;
}
|
protected Vector<ClusterNode> getNewMembers(Vector<ClusterNode> oldMembers,
Vector<ClusterNode> allMembers) {
if(oldMembers == null)
{
oldMembers=new Vector< ClusterNode >();
}
if(allMembers == null)
{
allMembers=new Vector< ClusterNode >();
}
Vector< ClusterNode > newMembers=(Vector< ClusterNode >)allMembers.clone();
newMembers.removeAll(oldMembers);
return newMembers;
}
Helper method that returns a vector of new members from two input vectors: new and old vectors of two views. |
public InetAddress getNodeAddress() {
return this.nodeAddress;
}
|
public String getNodeName() {
return this.nodeName;
}
|
public String getPartitionName() {
return this.partitionName;
}
|
public long getStateTransferTimeout() {
return this.state_transfer_timeout;
}
|
public ThreadPool getThreadPool() {
return this.threadPool;
}
|
public boolean isCurrentNodeCoordinator() {
if(this.members == null || this.members.size() == 0 || this.me == null)
{
return false;
}
return this.members.elementAt (0).equals (this.me);
}
|
public void logHistory(String message) {
try
{
this.history.add(new SimpleDateFormat().format (new Date()) + " : " + message);
}
catch (Exception ignored){}
}
|
protected void notifyListeners(ArrayList<HAMembershipListener> theListeners,
long viewID,
Vector<ClusterNode> allMembers,
Vector<ClusterNode> deadMembers,
Vector<ClusterNode> newMembers,
Vector<View> originatingGroups) {
this.log.debug("Begin notifyListeners, viewID: "+viewID);
synchronized(theListeners)
{
// JBAS-3619 -- don't hold synch lock while notifying
theListeners = (ArrayList< HAMembershipListener >) theListeners.clone();
}
for (int i = 0; i < theListeners.size(); i++)
{
HAMembershipListener aListener = null;
try
{
aListener = theListeners.get(i);
if(originatingGroups != null && (aListener instanceof HAMembershipExtendedListener))
{
HAMembershipExtendedListener exListener = (HAMembershipExtendedListener) aListener;
exListener.membershipChangedDuringMerge (deadMembers, newMembers,
allMembers, originatingGroups);
}
else
{
aListener.membershipChanged(deadMembers, newMembers, allMembers);
}
}
catch (Throwable e)
{
// a problem in a listener should not prevent other members to receive the new view
this.log.warn("HAMembershipListener callback failure: "+aListener, e);
}
}
this.log.debug("End notifyListeners, viewID: "+viewID);
}
|
protected Object objectFromByteBufferInternal(byte[] buffer) throws Exception {
if(buffer == null)
{
return null;
}
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
MarshalledValueInputStream mvis = new MarshalledValueInputStream(bais);
return mvis.readObject();
}
Creates an object from a byte buffer |
protected Object objectFromByteBufferResponseInternal(byte[] buffer) throws Exception {
if(buffer == null)
{
return null;
}
if (buffer[0] == NULL_VALUE)
{
return null;
}
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
// read past the null/serializable byte
bais.read();
MarshalledValueInputStream mvis = new MarshalledValueInputStream(bais);
return mvis.readObject();
}
Creates a response object from a byte buffer - optimized for response marshalling |
protected byte[] objectToByteBufferInternal(Object obj) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
MarshalledValueOutputStream mvos = new MarshalledValueOutputStream(baos);
mvos.writeObject(obj);
mvos.flush();
return baos.toByteArray();
}
Serializes an object into a byte buffer.
The object has to implement interface Serializable or Externalizable |
protected byte[] objectToByteBufferResponseInternal(Object obj) throws Exception {
if (obj == null)
{
return new byte[]{NULL_VALUE};
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// write a marker to stream to distinguish from null value stream
baos.write(SERIALIZABLE_VALUE);
MarshalledValueOutputStream mvos = new MarshalledValueOutputStream(baos);
mvos.writeObject(obj);
mvos.flush();
return baos.toByteArray();
}
Serializes a response object into a byte buffer, optimized for response marshalling.
The object has to implement interface Serializable or Externalizable |
public void processEvent(Object event) {
ViewChangeEvent vce = (ViewChangeEvent) event;
this.notifyListeners(this.asynchListeners, vce.viewId, vce.allMembers,
vce.deadMembers, vce.newMembers, vce.originatingGroups);
}
|
public void registerMembershipListener(HAMembershipListener listener) {
boolean isAsynch = (this.allowSyncListeners == false)
|| (listener instanceof AsynchHAMembershipListener)
|| (listener instanceof AsynchHAMembershipExtendedListener);
if( isAsynch ) {
synchronized(this.asynchListeners) {
this.asynchListeners.add(listener);
}
}
else {
synchronized(this.synchListeners) {
this.synchListeners.add(listener);
}
}
}
|
public void registerRPCHandler(String objName,
Object subscriber) {
this.rpcHandlers.put(objName, subscriber);
}
|
public void registerRPCHandler(String objName,
Object subscriber,
ClassLoader classloader) {
this.registerRPCHandler(objName, subscriber);
this.clmap.put(objName, new WeakReference< ClassLoader >(classloader));
}
|
public void setAllowSynchronousMembershipNotifications(boolean allowSync) {
this.allowSyncListeners = allowSync;
}
Sets whether this partition will synchronously notify any
HAPartition.HAMembershipListener of membership changes using the
calling thread from the underlying group communications layer
(e.g. JGroups). |
public void setBindIntoJndi(boolean bind) {
this.bindIntoJndi = bind;
}
|
public void setCacheHandler(HAPartitionCacheHandler cacheHandler) {
this.cacheHandler = cacheHandler;
this.cacheConfigName = cacheHandler == null ? null : cacheHandler.getCacheConfigName();
}
|
public void setDeadlockDetection(boolean doit) {
log.warn("Property deadlockDetection has been deprecated; setting it has no effect");
} Deprecated! will - be removed in next major release
Deprecated; logs a WARN message if invoked. |
public void setDistributedStateImpl(DistributedState distributedState) {
this.distributedState = distributedState;
}
|
public synchronized void setHaPartitionDependencyCreator(HAPartitionDependencyCreator haPartitionDependencyCreator) {
this.haPartitionDependencyCreator = haPartitionDependencyCreator;
}
|
public void setKernelControllerContext(KernelControllerContext controllerContext) throws Exception {
super.setKernelControllerContext(controllerContext);
this.kernelControllerContext = controllerContext;
}
|
public void setMethodCallTimeout(long timeout) {
this.method_call_timeout = timeout;
}
|
public void setNodeAddress(InetAddress address) {
this.nodeAddress = address;
}
|
public void setPartitionName(String newName) {
this.partitionName = newName;
}
|
public void setStateTransferTimeout(long timeout) {
this.state_transfer_timeout = timeout;
}
|
public void setThreadPool(ThreadPool threadPool) {
this.threadPool = threadPool;
}
|
public String showHistory() {
StringBuffer buff = new StringBuffer();
Vector< String > data = new Vector< String >(this.history);
for (java.util.Iterator< String > row = data.iterator(); row.hasNext();)
{
String info = row.next();
buff.append(info).append("\n");
}
return buff.toString();
}
|
public String showHistoryAsXML() {
StringBuffer buff = new StringBuffer();
buff.append("< events >\n");
Vector< String > data = new Vector< String >(this.history);
for (java.util.Iterator< String > row = data.iterator(); row.hasNext();)
{
buff.append(" < event >\n ");
String info = row.next();
buff.append(info);
buff.append("\n < /event >\n");
}
buff.append("< /events >\n");
return buff.toString();
}
|
protected void startService() throws Exception {
this.logHistory ("Starting partition");
// Have the handler get the cache
this.cacheHandler.acquireCache();
this.channelFactory = this.cacheHandler.getCacheChannelFactory();
this.stackName = this.cacheHandler.getChannelStackName();
if (this.channel == null || !this.channel.isOpen())
{
this.log.debug("Creating Channel for partition " + this.getPartitionName() +
" using stack " + this.getChannelStackName());
this.channel = this.createChannel();
this.channel.setOpt(Channel.AUTO_RECONNECT, Boolean.TRUE);
this.channel.setOpt(Channel.AUTO_GETSTATE, Boolean.TRUE);
}
this.log.info("Initializing partition " + this.getPartitionName());
this.logHistory ("Initializing partition " + this.getPartitionName());
this.dispatcher = new RpcHandler(this.channel, null, null, new Object(), false);
// Subscribe to events generated by the channel
this.log.debug("setMembershipListener");
this.dispatcher.setMembershipListener(this);
this.log.debug("setMessageListener");
this.dispatcher.setMessageListener(this.messageListener);
this.dispatcher.setRequestMarshaller(new RequestMarshallerImpl());
this.dispatcher.setResponseMarshaller(new ResponseMarshallerImpl());
// Clear any old connectException
this.connectException = null;
CountDownLatch connectLatch = new CountDownLatch(1);
if (this.threadPool == null)
{
this.channel.connect(this.getPartitionName());
connectLatch.countDown();
}
else
{
// Do the channel connect in another thread while this
// thread starts the cache and does that channel connect
ChannelConnectTask task = new ChannelConnectTask(connectLatch);
this.threadPool.run(task);
}
this.cacheHandler.startCache();
try
{
// This will block waiting for any async channel connect above
connectLatch.await();
if (this.connectException != null)
{
throw this.connectException;
}
this.log.debug("Get current members");
this.waitForView();
// get current JG group properties
this.log.debug("get nodeName");
this.localJGAddress = this.channel.getLocalAddress();
this.me = new ClusterNodeImpl((IpAddress) this.localJGAddress);
this.nodeName = this.me.getName();
this.verifyNodeIsUnique();
this.fetchState();
this.replicantManager.startService();
if (this.distributedState instanceof ManagedDistributedState)
{
((ManagedDistributedState) this.distributedState).startService();
}
// Start the asynch listener handler thread
this.asynchHandler.start();
// Register with the service locator
HAPartitionLocator.getHAPartitionLocator().registerHAPartition(this);
// Bind ourself in the public JNDI space if configured to do so
if (this.bindIntoJndi)
{
Context ctx = new InitialContext();
this.bind(HAPartitionLocator.getStandardJndiBinding(this.getPartitionName()),
this, ClusterPartition.class, ctx);
this.log.debug("Bound in JNDI under /HAPartition/" + this.getPartitionName());
}
}
catch (Throwable t)
{
this.log.debug("Caught exception after channel connected; closing channel -- " + t.getLocalizedMessage());
this.channel.close();
this.channel = null;
throw (t instanceof Exception) ? (Exception) t : new RuntimeException(t);
}
}
|
protected void stopService() throws Exception {
this.logHistory ("Stopping partition");
this.log.info("Stopping partition " + this.getPartitionName());
try
{
this.asynchHandler.stop();
}
catch( Exception e)
{
this.log.warn("Failed to stop asynchHandler", e);
}
if (this.distributedState instanceof ManagedDistributedState)
{
((ManagedDistributedState) this.distributedState).stopService();
}
this.replicantManager.stopService();
try
{
this.cacheHandler.releaseCache();
}
catch (Exception e)
{
this.log.error("cache release failed", e);
}
// NR 200505 : [JBCLUSTER-38] replace channel.close() by a disconnect and
// add the destroyPartition() step
try
{
if (this.channel != null && this.channel.isConnected())
{
this.channel.disconnect();
}
}
catch (Exception e)
{
this.log.error("channel disconnection failed", e);
}
if (this.bindIntoJndi)
{
String boundName = HAPartitionLocator.getStandardJndiBinding(this.getPartitionName());
InitialContext ctx = null;
try
{
// the following statement fails when the server is being shut down (07/19/2007)
ctx = new InitialContext();
ctx.unbind(boundName);
}
catch (Exception e) {
this.log.error("partition unbind operation failed", e);
}
finally
{
if (ctx != null)
{
ctx.close();
}
}
NonSerializableFactory.unbind(boundName);
}
HAPartitionLocator.getHAPartitionLocator().deregisterHAPartition(this);
this.log.info("Partition " + this.getPartitionName() + " stopped.");
}
|
public void subscribeToStateTransferEvents(String objectName,
HAPartitionStateTransfer subscriber) {
this.stateHandlers.put(objectName, subscriber);
}
|
public void suspect(Address suspected_mbr) {
this.logHistory ("Node suspected: " + (suspected_mbr==null?"null":suspected_mbr.toString()));
if (this.isCurrentNodeCoordinator ())
{
this.clusterLifeCycleLog.info ("Suspected member: " + suspected_mbr);
}
else
{
this.log.info("Suspected member: " + suspected_mbr);
}
}
|
protected Vector<ClusterNode> translateAddresses(Vector<Address> addresses) {
if (addresses == null)
{
return null;
}
Vector< ClusterNode > result = new Vector< ClusterNode >(addresses.size());
for (Address address: addresses)
{
result.add(new ClusterNodeImpl((IpAddress) address));
}
return result;
}
|
public void unblock() {
this.flushBlockGate.open();
this.log.debug("Unblock processed at " + this.me);
}
|
public void unregisterMembershipListener(HAMembershipListener listener) {
boolean isAsynch = (this.allowSyncListeners == false)
|| (listener instanceof AsynchHAMembershipListener)
|| (listener instanceof AsynchHAMembershipExtendedListener);
if( isAsynch ) {
synchronized(this.asynchListeners) {
this.asynchListeners.remove(listener);
}
}
else {
synchronized(this.synchListeners) {
this.synchListeners.remove(listener);
}
}
}
|
public void unregisterRPCHandler(String objName,
Object subscriber) {
this.rpcHandlers.remove(objName);
this.clmap.remove(objName);
}
|
public void unsetKernelControllerContext(KernelControllerContext controllerContext) throws Exception {
super.unsetKernelControllerContext(controllerContext);
this.kernelControllerContext = null;
}
|
public void unsubscribeFromStateTransferEvents(String objectName,
HAPartitionStateTransfer subscriber) {
this.stateHandlers.remove(objectName);
}
|
protected void verifyNodeIsUnique() throws IllegalStateException {
ClusterNodeImpl matched = null;
for (ClusterNode member : this.getClusterNodes())
{
if (member.equals(this.me))
{
if (matched == null)
{
// We of course are in the view, so we expect one match
// Just track that we've had one
matched = (ClusterNodeImpl) member;
}
else
{
// Two nodes in view match us; try to figure out which one isn't us
ClusterNodeImpl other = matched;
if (other.getOriginalJGAddress().equals(((ClusterNodeImpl)this.me).getOriginalJGAddress()))
{
other = (ClusterNodeImpl) member;
}
throw new IllegalStateException("Found member " + other +
" in current view that duplicates us (" + this.me + "). This" +
" node cannot join partition until duplicate member has" +
" been removed");
}
}
}
}
|
public void viewAccepted(View newView) {
try
{
// we update the view id
this.currentViewId = newView.getVid().getId();
// Keep a list of other members only for "exclude-self" RPC calls
this.jgotherMembers = (Vector< Address >)newView.getMembers().clone();
this.jgotherMembers.remove (this.channel.getLocalAddress());
this.otherMembers = this.translateAddresses (this.jgotherMembers); // TRANSLATE!
Vector< ClusterNode > translatedNewView = this.translateAddresses ((Vector< Address >)newView.getMembers().clone());
this.logHistory ("New view: " + translatedNewView + " with viewId: " + this.currentViewId +
" (old view: " + this.members + " )");
// Save the previous view and make a copy of the new view
Vector< ClusterNode > oldMembers = this.members;
Vector< Address > newjgMembers = (Vector< Address >)newView.getMembers().clone();
Vector< ClusterNode > newMembers = this.translateAddresses(newjgMembers); // TRANSLATE
this.members = newMembers;
this.jgmembers = newjgMembers;
if (oldMembers == null)
{
// Initial viewAccepted
this.log.debug("ViewAccepted: initial members set for partition " + this.getPartitionName() + ": " +
this.currentViewId + " (" + this.members + ")");
this.log.info("Number of cluster members: " + this.members.size());
for(int m = 0; m > this.members.size(); m ++)
{
Object node = this.members.get(m);
this.log.debug(node);
}
this.log.info ("Other members: " + this.otherMembers.size ());
// Wake up the deployer thread blocking in waitForView
this.notifyChannelLock();
return;
}
int difference = newMembers.size() - oldMembers.size();
if (this.isCurrentNodeCoordinator ())
{
this.clusterLifeCycleLog.info ("New cluster view for partition " + this.getPartitionName() + " (id: " +
this.currentViewId + ", delta: " + difference + ") : " + this.members);
}
else
{
this.log.info("New cluster view for partition " + this.getPartitionName() + ": " +
this.currentViewId + " (" + this.members + " delta: " + difference + ")");
}
// Build a ViewChangeEvent for the asynch listeners
ViewChangeEvent event = new ViewChangeEvent();
event.viewId = this.currentViewId;
event.allMembers = translatedNewView;
event.deadMembers = this.getDeadMembers(oldMembers, event.allMembers);
event.newMembers = this.getNewMembers(oldMembers, event.allMembers);
event.originatingGroups = null;
// if the new view occurs because of a merge, we first inform listeners of the merge
if(newView instanceof MergeView)
{
MergeView mergeView = (MergeView) newView;
event.originatingGroups = mergeView.getSubgroups();
}
this.log.debug("membership changed from " + oldMembers.size() + " to " + event.allMembers.size());
// Put the view change to the asynch queue
this.asynchHandler.queueEvent(event);
// Broadcast the new view to the synchronous view change listeners
if (this.allowSyncListeners)
{
this.notifyListeners(this.synchListeners, event.viewId, event.allMembers,
event.deadMembers, event.newMembers, event.originatingGroups);
}
}
catch (Exception ex)
{
this.log.error("ViewAccepted failed", ex);
}
}
Notification of a cluster view change. This is done from the JG protocol
handlder thread and we must be careful to not unduly block this thread.
Because of this there are two types of listeners, synchronous and
asynchronous. The synchronous listeners are messaged with the view change
event using the calling thread while the asynchronous listeners are
messaged using a seperate thread. |