FileDocCategorySizeDatePackage
TwoPhaseCommitInterceptor.javaAPI DocApache Tomcat 6.0.146302Fri Jul 20 04:20:32 BST 2007org.apache.catalina.tribes.group.interceptors

TwoPhaseCommitInterceptor

public class TwoPhaseCommitInterceptor extends org.apache.catalina.tribes.group.ChannelInterceptorBase

Title:

Description:

Company:

author
not attributable
version
1.0

Fields Summary
public static final byte[]
START_DATA
public static final byte[]
END_DATA
private static org.apache.juli.logging.Log
log
protected HashMap
messages
protected long
expire
protected boolean
deepclone
Constructors Summary
Methods Summary
public booleangetDeepclone()

        return deepclone;
    
public longgetExpire()

        return expire;
    
public voidheartbeat()

        try {
            long now = System.currentTimeMillis();
            Map.Entry[] entries = (Map.Entry[])messages.entrySet().toArray(new Map.Entry[messages.size()]);
            for (int i=0; i<entries.length; i++ ) {
                MapEntry entry = (MapEntry)entries[i].getValue();
                if ( entry.expired(now,expire) ) {
                    if(log.isInfoEnabled())
                        log.info("Message ["+entry.id+"] has expired. Removing.");
                    messages.remove(entry.id);
                }//end if
            }
        } catch ( Exception x ) {
            log.warn("Unable to perform heartbeat on the TwoPhaseCommit interceptor.",x);
        } finally {
            super.heartbeat();
        }
    
public voidmessageReceived(org.apache.catalina.tribes.ChannelMessage msg)

        if (okToProcess(msg.getOptions())) {
            if ( msg.getMessage().getLength() == (START_DATA.length+msg.getUniqueId().length+END_DATA.length) &&
                 Arrays.contains(msg.getMessage().getBytesDirect(),0,START_DATA,0,START_DATA.length) &&
                 Arrays.contains(msg.getMessage().getBytesDirect(),START_DATA.length+msg.getUniqueId().length,END_DATA,0,END_DATA.length) ) {
                UniqueId id = new UniqueId(msg.getMessage().getBytesDirect(),START_DATA.length,msg.getUniqueId().length);
                MapEntry original = (MapEntry)messages.get(id);
                if ( original != null ) {
                    super.messageReceived(original.msg);
                    messages.remove(id);
                } else log.warn("Received a confirmation, but original message is missing. Id:"+Arrays.toString(id.getBytes()));
            } else {
                UniqueId id = new UniqueId(msg.getUniqueId());
                MapEntry entry = new MapEntry((ChannelMessage)msg.deepclone(),id,System.currentTimeMillis());
                messages.put(id,entry);
            }
        } else {
            super.messageReceived(msg);
        }
    
public voidsendMessage(org.apache.catalina.tribes.Member[] destination, org.apache.catalina.tribes.ChannelMessage msg, org.apache.catalina.tribes.group.InterceptorPayload payload)


            
         
        //todo, optimize, if destination.length==1, then we can do
        //msg.setOptions(msg.getOptions() & (~getOptionFlag())
        //and just send one message
        if (okToProcess(msg.getOptions()) ) {
            super.sendMessage(destination, msg, null);
            ChannelMessage confirmation = null;
            if ( deepclone ) confirmation = (ChannelMessage)msg.deepclone();
            else confirmation = (ChannelMessage)msg.clone();
            confirmation.getMessage().reset();
            UUIDGenerator.randomUUID(false,confirmation.getUniqueId(),0);
            confirmation.getMessage().append(START_DATA,0,START_DATA.length);
            confirmation.getMessage().append(msg.getUniqueId(),0,msg.getUniqueId().length);
            confirmation.getMessage().append(END_DATA,0,END_DATA.length);
            super.sendMessage(destination,confirmation,payload);
        } else {
            //turn off two phase commit
            //this wont work if the interceptor has 0 as a flag
            //since there is no flag to turn off
            //msg.setOptions(msg.getOptions() & (~getOptionFlag()));
            super.sendMessage(destination, msg, payload);
        }
    
public voidsetDeepclone(boolean deepclone)

        this.deepclone = deepclone;
    
public voidsetExpire(long expire)

        this.expire = expire;