All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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_;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy