@Override public void notify(ChangeSet changeSet) { if (changeSet == null) { return; // do nothing } if (!isOpen.get()) { // The channel is not open ... return; } if (!multipleAddressesInCluster.get()) { // We are in clustered mode, but there is only one participant in the cluster (us). // So short-circuit the cluster and just notify the local observers ... if (hasObservers()) { delegate.notify(changeSet); logReceivedOperation(changeSet); } return; } // There are multiple participants in the cluster, so send all changes out to JGroups, // letting JGroups do the ordering of messages... try { logSendOperation(changeSet); byte[] data = serialize(changeSet); Message message = new Message(null, null, data); channel.send(message); } catch (IllegalStateException e) { LOGGER.warn( BusI18n.unableToNotifyChanges, clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp()); } catch (Exception e) { // Something went wrong here (this should not happen) ... String msg = BusI18n.errorSerializingChanges.text( clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp(), changeSet); throw new SystemFailureException(msg, e); } }
@Override public synchronized void start() throws Exception { String clusterName = clusteringConfiguration.getClusterName(); if (clusterName == null) { throw new IllegalStateException(BusI18n.clusterNameRequired.text()); } if (channel != null) { // Disconnect from any previous channel ... channel.removeChannelListener(listener); channel.setReceiver(null); } // Create the new channel by calling the delegate method ... channel = newChannel(); // Add a listener through which we'll know what's going on within the cluster ... channel.addChannelListener(listener); // Set the receiver through which we'll receive all of the changes ... channel.setReceiver(receiver); // Now connect to the cluster ... channel.connect(clusterName); // start the delegate delegate.start(); }
public ClusteredRepositoryChangeBus( RepositoryConfiguration.Clustering clusteringConfiguration, ChangeBus delegate) { CheckArg.isNotNull(clusteringConfiguration, "clusteringConfiguration"); CheckArg.isNotNull(delegate, "delegate"); this.clusteringConfiguration = clusteringConfiguration; assert clusteringConfiguration.isEnabled(); this.delegate = delegate; }
private Channel newChannel() throws Exception { // Try to get the channel directly from the configuration (and its environment) ... Channel channel = clusteringConfiguration.getChannel(); if (channel != null) { return channel; } String lookupClassName = clusteringConfiguration.getChannelProviderClassName(); assert lookupClassName != null; Class<?> lookupClass = Class.forName(lookupClassName); if (!ChannelProvider.class.isAssignableFrom(lookupClass)) { throw new IllegalArgumentException( "Invalid channel lookup class configured. Expected a subclass of org.modeshape.jcr.clustering.ChannelProvider. Actual class:" + lookupClass); } return ((ChannelProvider) lookupClass.newInstance()).getChannel(clusteringConfiguration); }
protected final void logReceivedOperation(ChangeSet changeSet) { if (LOGGER.isTraceEnabled()) { LOGGER.trace( "Received on cluster '{0}' {1} changes on workspace {2} made by {3} from process '{4}' at {5}", clusteringConfiguration.getClusterName(), changeSet.size(), changeSet.getWorkspaceName(), changeSet.getUserId(), changeSet.getProcessKey(), changeSet.getTimestamp()); } }