/* Function : decodeVersionAndState * Arguments : stream - socket, through which the data is received * Description: receives remote replication daemon version and state from the * given socket */ Version* ReplicatorStateMachine::decodeVersionAndState( Stream* stream ) { Version* newVersion = new Version; // decode remote replication daemon version if( ! newVersion->decode( stream ) ) { dprintf( D_ALWAYS, "ReplicatorStateMachine::decodeVersionAndState " "cannot read remote daemon version\n" ); delete newVersion; return 0; } int remoteReplicatorState; stream->decode( ); // decode remore replication daemon state if( ! stream->code( remoteReplicatorState ) ) { dprintf( D_ALWAYS, "ReplicatorStateMachine::decodeVersionAndState " "unable to decode the state\n" ); delete newVersion; return 0; } newVersion->setState( ReplicatorState( remoteReplicatorState ) ); return newVersion; //updateVersionsList( *newVersion ); }
void AbstractReplicatorStateMachine::cancelVersionsListLeader( ) { Version* version; m_versionsList.Rewind( ); while( m_versionsList.Next( version ) ) { version->setState( BACKUP ); } m_versionsList.Rewind( ); }
bool ReplicatorStateMachine::replicaSelectionHandler( Version& newVersion ) { REPLICATION_ASSERT( m_state == VERSION_DOWNLOADING || m_state == BACKUP ); dprintf( D_ALWAYS, "ReplicatorStateMachine::replicaSelectionHandler " "started with my version = %s, #versions = %d\n", m_myVersion.toString( ).Value( ), m_versionsList.Number( ) ); List<Version> actualVersionsList; Version myVersionCopy = m_myVersion; utilCopyList( actualVersionsList, m_versionsList ); // in BACKUP state compares the received version with the local one if( m_state == BACKUP ) { // compares the versions, taking only 'gid' and 'logicalClock' into // account - this is the reason for making the states equal myVersionCopy.setState( newVersion ); return ! newVersion.isComparable( myVersionCopy ) || newVersion > myVersionCopy; } /* in VERSION_DOWNLOADING state selecting the best version from the list of * received versions according to the policy defined by * 'replicaSelectionHandler', i.e. selecting the version with greatest * 'logicalClock' value amongst a group of versions with the same gid */ actualVersionsList.Rewind( ); if( actualVersionsList.IsEmpty( ) ) { return false; } Version version; Version bestVersion; // taking the first actual version as the best version in the meantime actualVersionsList.Next( bestVersion ); dprintf( D_ALWAYS, "ReplicatorStateMachine::replicaSelectionHandler best " "version = %s\n", bestVersion.toString( ).Value( ) ); while( actualVersionsList.Next( version ) ) { dprintf( D_ALWAYS, "ReplicatorStateMachine::replicaSelectionHandler " "actual version = %s\n", version.toString( ).Value( ) ); if( version.isComparable( bestVersion ) && version > bestVersion ) { bestVersion = version; } } actualVersionsList.Rewind( ); // compares the versions, taking only 'gid' and 'logicalClock' into // account - this is the reason for making the states equal myVersionCopy.setState( bestVersion ); // either when the versions are incomparable or when the local version // is worse, the remote version must be downloaded if( myVersionCopy.isComparable( bestVersion ) && myVersionCopy >= bestVersion ) { return false; } newVersion = bestVersion; dprintf( D_ALWAYS, "ReplicatorStateMachine::replicaSelectionHandler " "best version selected: %s\n", newVersion.toString().Value()); return true; }