/* Function   : onLeaderVersion
 * Arguments  : stream - socket, through which the data is received and sent
 * Description: handler of REPLICATION_LEADER_VERSION command; comparing the
 *				received version to the local one and downloading the replica
 *				from the remote replication daemon when the received version is
 *				better than the local one and there is no downloading
 *				'condor_transferer' running at the same time
 */
void
ReplicatorStateMachine::onLeaderVersion( Stream* stream )
{
    dprintf( D_ALWAYS, "ReplicatorStateMachine::onLeaderVersion started\n" );
    
    if( m_state != BACKUP ) {
        return ;
    }
	checkVersionSynchronization( );

    Version* newVersion = decodeVersionAndState( stream );
	// comparing the received version to the local one
    bool downloadNeeded = replicaSelectionHandler( *newVersion );
    // downloading the replica from the remote replication daemon, when the
	// received version is better and there is no running downloading
	// 'condor_transferers'  
    if( downloadTransferersNumber( ) == 0 && newVersion && downloadNeeded ) {
        dprintf( D_FULLDEBUG, "ReplicatorStateMachine::onLeaderVersion "
				"downloading from %s\n", 
				newVersion->getSinfulString( ).Value( ) );
        download( newVersion->getSinfulString( ).Value( ) );
    }
    // replication leader must not send a version which hasn't been updated
    //assert(downloadNeeded);
    //REPLICATION_ASSERT(downloadNeeded);
	delete newVersion;
}
/* Function   : versionRequestingTimer
 * Description: timer, expiration of which means stopping collecting the pool
 *				versions in VERSION_REQUESTING state, passing to
 *				VERSION_DOWNLOADING state and starting downloading from the
 *				machine with the best version
 */
void
ReplicatorStateMachine::versionRequestingTimer( )
{
    dprintf( D_ALWAYS, 
			"ReplicatorStateMachine::versionRequestingTimer started\n" );
    utilCancelTimer(m_versionRequestingTimerId);
    dprintf( D_FULLDEBUG, "ReplicatorStateMachine::versionRequestingTimer "
			"cancelling version requesting timer\n" );
    m_state = VERSION_DOWNLOADING;
    // selecting the best version amongst all the versions that have been sent
    // by other replication daemons
    Version updatedVersion;

    if( replicaSelectionHandler( updatedVersion ) ) {
        download( updatedVersion.getSinfulString( ).Value( ) );
        dprintf( D_FULLDEBUG, "ReplicatorStateMachine::versionRequestingTimer "
				"registering version downloading timer\n" );
        m_versionDownloadingTimerId = daemonCore->Register_Timer( 
			m_maxTransfererLifeTime,
            (TimerHandlercpp) &ReplicatorStateMachine::versionDownloadingTimer,
            "Time to pass to BACKUP state", this );
    } else {
        versionDownloadingTimer( );
    }
}