com.atomikos.icatch.imp.PrepareResult Maven / Gradle / Ivy
/**
* Copyright (C) 2000-2023 Atomikos
*
* LICENSE CONDITIONS
*
* See http://www.atomikos.com/Main/WhichLicenseApplies for details.
*/
package com.atomikos.icatch.imp;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import com.atomikos.icatch.HeurCommitException;
import com.atomikos.icatch.HeurHazardException;
import com.atomikos.icatch.HeurMixedException;
import com.atomikos.icatch.Participant;
/**
* A result for prepare messages.
*/
class PrepareResult extends Result
{
private Set readonlytable_ = new HashSet ();
// for read only voters
private Set indoubts_ = new HashSet();
// for indoubt participants
// should be rolled back in case of failure!
private boolean analyzed_ = false;
/**
* Constructor.
*
* @param count
* The number of replies to deal with.
*/
public PrepareResult ( int count )
{
super ( count );
}
protected synchronized void calculateResultFromAllReplies () throws IllegalStateException,
InterruptedException
{
if ( analyzed_ )
return;
boolean allReadOnly = true;
boolean allYes = true;
boolean heurmixed = false;
boolean heurhazards = false;
boolean heurcommits = false;
Stack replies = getReplies ();
Enumeration enumm = replies.elements ();
while ( enumm.hasMoreElements () ) {
boolean yes = false;
boolean readonly = false;
Reply reply = (Reply) enumm.nextElement ();
if ( reply.hasFailed () ) {
yes = false;
readonly = false;
Exception err = reply.getException ();
if ( err instanceof HeurMixedException ) {
heurmixed = true;
} else if ( err instanceof HeurCommitException ) {
heurcommits = true;
heurmixed = (heurmixed || heurhazards);
} else if ( err instanceof HeurHazardException ) {
heurhazards = true;
heurmixed = (heurmixed || heurcommits);
indoubts_.add ( reply.getParticipant ());
// REMEMBER: might be indoubt, so HAS to be notified
// during rollback!
}
}// if failed
else {
readonly = (reply.getResponse () == null);
Boolean answer = new Boolean ( false );
if ( !readonly ) {
answer = (Boolean) reply.getResponse ();
}
yes = (readonly || answer.booleanValue ());
// if readonly: remember this fact for logging and second phase
if ( readonly ) readonlytable_.add ( reply.getParticipant () );
else indoubts_.add ( reply.getParticipant ());
}
allYes = (allYes && yes);
allReadOnly = (allReadOnly && readonly);
}
if ( heurmixed )
result_ = HEUR_MIXED;
else if ( heurcommits )
result_ = HEUR_COMMIT;
else if ( heurhazards )
result_ = HEUR_HAZARD;
else if ( allReadOnly )
result_ = ALL_READONLY;
else if ( allYes )
result_ = ALL_OK;
analyzed_ = true;
}
/**
* Test if all answers represent a yes vote. Blocks until all results
* arrived.
*
* @return boolean True if all are yes, false if not.
* @exception InterruptedException
* If interrupt on wait.
*/
public boolean allYes () throws InterruptedException
{
calculateResultFromAllReplies ();
return (result_ == ALL_OK || result_ == ALL_READONLY);
}
/**
* Test if all answers were readonly votes. Blocks till all results known.
*
* @return boolean True if all readonly, false otherwise.
* @exception InterruptedException
* If interrupted.
*/
public boolean allReadOnly () throws InterruptedException
{
calculateResultFromAllReplies ();
return (result_ == ALL_READONLY);
}
/**
* Get a table of readonly voting participants.
*
* @return Set Contains readonly participant.
* @exception InterruptedException
* If interrupted on wait.
*/
public Set getReadOnlyTable () throws InterruptedException
{
calculateResultFromAllReplies ();
return readonlytable_;
}
}