// until the state files merging utility is ready, the function is not really // interesting, it selects 0 as the next gid each time void ReplicatorStateMachine::gidSelectionHandler( ) { REPLICATION_ASSERT( m_state == BACKUP || m_state == REPLICATION_LEADER ); dprintf( D_ALWAYS, "ReplicatorStateMachine::gidSelectionHandler started\n"); bool areVersionsComparable = true; List<Version> actualVersionsList; Version actualVersion; utilCopyList( actualVersionsList, m_versionsList ); while( actualVersionsList.Next( actualVersion ) ) { if( ! m_myVersion.isComparable( actualVersion ) ) { areVersionsComparable = false; break; } } actualVersionsList.Rewind( ); if( areVersionsComparable ) { dprintf( D_ALWAYS, "ReplicatorStateMachine::gidSelectionHandler no " "need to select new gid\n" ); return ; } int temporaryGid = 0; while( ( temporaryGid = rand( ) ) == m_myVersion.getGid( ) ) { } m_myVersion.setGid( temporaryGid ); dprintf( D_ALWAYS, "ReplicatorStateMachine::gidSelectionHandler " "new gid selected: %d\n", temporaryGid ); //myVersion.setSinfulString( daemonCore->InfoCommandSinfulString( ) ); }
// creating downloading transferer process and remembering its pid and creation // time bool AbstractReplicatorStateMachine::download( const char* daemonSinfulString ) { ArgList processArguments; processArguments.AppendArg( m_transfererPath.Value() ); processArguments.AppendArg( "-f" ); processArguments.AppendArg( "down" ); processArguments.AppendArg( daemonSinfulString ); processArguments.AppendArg( m_versionFilePath.Value() ); processArguments.AppendArg( "1" ); processArguments.AppendArg( m_stateFilePath.Value() ); // Get arguments from this ArgList object for descriptional purposes. MyString s; processArguments.GetArgsStringForDisplay( &s ); dprintf( D_FULLDEBUG, "AbstractReplicatorStateMachine::download creating " "downloading condor_transferer process: \n \"%s\"\n", s.Value( ) ); // PRIV_ROOT privilege is necessary here to create the process // so we can read GSI certs <sigh> priv_state privilege = PRIV_ROOT; int transfererPid = daemonCore->Create_Process( m_transfererPath.Value( ), // name processArguments, // args privilege, // priv m_downloadReaperId, // reaper id FALSE, // command port needed? FALSE, // command port needed? NULL, // env NULL, // cwd NULL // process family info ); if( transfererPid == FALSE ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::download unable to create " "downloading condor_transferer process\n" ); return false; } else { dprintf( D_FULLDEBUG, "AbstractReplicatorStateMachine::download downloading " "condor_transferer process created with pid = %d\n", transfererPid ); REPLICATION_ASSERT( ! m_downloadTransfererMetadata.isValid() ); /* Remembering the last time, when the downloading 'condor_transferer' * was created: the monitoring might be useful in possible prevention * of stuck 'condor_transferer' processes. Remembering the pid of the * downloading process as well: to terminate it when the downloading * process is stuck */ m_downloadTransfererMetadata.set(transfererPid, time( NULL ) ); } return true; }
void ReplicatorStateMachine::afterElectionStateHandler() { dprintf( D_ALWAYS, "ReplicatorStateMachine::afterElectionStateHandler " "started\n" ); REPLICATION_ASSERT(m_state != REPLICATION_LEADER); // we stay in VERSION_REQUESTING or VERSION_DOWNLOADING state // of newly joining node, we will go to LEADER_STATE later // upon receiving of IN_LEADER message from HAD if( m_state == VERSION_REQUESTING || m_state == VERSION_DOWNLOADING ) { return ; } becomeLeader( ); }
// sends the version of the last execution time to all the replication daemons, // then asks the pool replication daemons to send their own versions to it, // sets a timer to wait till the versions are received void ReplicatorStateMachine::beforePassiveStateHandler() { REPLICATION_ASSERT(m_state == VERSION_REQUESTING); dprintf( D_ALWAYS, "ReplicatorStateMachine::beforePassiveStateHandler started\n" ); broadcastVersion( REPLICATION_NEWLY_JOINED_VERSION ); requestVersions( ); dprintf( D_FULLDEBUG, "ReplicatorStateMachine::beforePassiveStateHandler " "registering version requesting timer\n" ); m_versionRequestingTimerId = daemonCore->Register_Timer( m_newlyJoinedWaitingVersionInterval, (TimerHandlercpp) &ReplicatorStateMachine::versionRequestingTimer, "Time to pass to VERSION_DOWNLOADING state", this ); }
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; }