Subversion Repositories DevTools

Rev

Rev 930 | Rev 4285 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.erggroup.buildtool.daemon;

import com.erggroup.buildtool.daemon.BuildThread;
import com.erggroup.buildtool.ripple.MutableInt;
import com.erggroup.buildtool.ripple.MutableString;
import com.erggroup.buildtool.ripple.Package;
import com.erggroup.buildtool.ripple.ReleaseManager;
import com.erggroup.buildtool.ripple.RippleEngine;

import java.io.File;
import java.sql.SQLException;
import org.apache.log4j.Logger;

/**Slave Thread sub component
 */
public class SlaveThread
  extends BuildThread
{

  /**Logger
   * @attribute
   */
  private static final Logger mLogger = Logger.getLogger(SlaveThread.class);

  /**constructor
   */
  public SlaveThread(int rtag_id, int rcon_id, String unitTest)
  {
    mLogger.warn("SlaveThread rtag_id " + rtag_id + " rcon_id " + rcon_id);
    mRtagId = rtag_id;
    mRconId = rcon_id;
    if ( unitTest == null )
    {
      unitTest = new String();
    }
    mUnitTest = unitTest;
  }

  /**implements the sequence diagrams consume build files, allowed to proceed, check environment
   */
  public void run()
  {
    Integer id = new Integer(mRtagId);
    setName(id.toString());
    mLogger.warn("run");
    boolean exit = false;
    RippleEngine rippleEngine = new RippleEngine(mReleaseManager, mRtagId, true);
    MutableString buildFileContent = new MutableString();

    while(!exit)
    {
      try
      {
        mLogger.fatal("run calling sleepCheck");
        sleepCheck();
        mLogger.fatal("run calling rippleEngine.collectMetaData");
        rippleEngine.collectMetaData();
        
        if ( Thread.currentThread().isInterrupted() )
        {
          mLogger.warn("run is interrupted");
          // unit test technique
          throw new ExitException();
        }
        
        if ( mUnitTest.compareTo("unit test spawn thread") == 0)
        {
          throw new Exception();
        }
        
        // allowed to proceed
        if ( mUnitTest.compareTo("unit test consume build files") != 0)
        {
          mRunLevel = RunLevel.IDLE;
          mLogger.warn("run changing run level to IDLE for rcon_id " + mRconId);
          mLogger.fatal("run calling rmRunLevel.persistNew to set IDLE");
          mRunLevel.persistNew(mReleaseManager, mRconId);

          mLogger.warn("run checking allowedToProceed");
          mLogger.fatal("run calling allowedToProceed");
          allowedToProceed(false);
          mLogger.info("run allowedToProceed returned");
        }
        
        mRunLevel = RunLevel.WAITING;
        mLogger.warn("run changing run level to WAITING for rcon_id " + mRconId);
        mLogger.fatal("run calling rmRunLevel.persist to set WAITING");
        mRunLevel.persist(mReleaseManager, mRconId);

        // consume build files
        mLogger.warn("run consume build files");
        buildFileContent.value = "";
        boolean logWarning = true;
        
        // additional handshake
        // Master waits for Slave to be in state waiting
        // wait for the Master to signal we are active
        MutableInt rconId = new MutableInt();
        MutableInt current_run_level = new MutableInt();
        
        do
        {
          mLogger.fatal("run calling mReleaseManager.querySingleRunLevel");
          mReleaseManager.querySingleRunLevel(mRconId);
          mLogger.fatal("run calling mReleaseManager.getFirstRunLevel");
          if ( !mReleaseManager.getFirstRunLevel(rconId, current_run_level) )
          {
            mLogger.warn("run no longer configured 1");
            throw new ExitException();
          }
          
          if (current_run_level.value != ReleaseManager.DB_ACTIVE)
          {
            try
            {
              if ( logWarning )
              {
                mLogger.warn("run sleep 3 secs waiting for Master to set Slave run level ACTIVE");
                logWarning = false;
              }
              else
              {
                mLogger.info("run sleep 3 secs waiting for Master to set Slave run level ACTIVE");
              }
              // to do, sleep for periodicMs
              mLogger.fatal("run calling Thread.sleep for 3 secs");
              Thread.sleep(3000);
              mLogger.info("run sleep returned");
            }
            catch (InterruptedException e)
            {
              mLogger.warn("run caught InterruptedException");
            }
          }
        } while (current_run_level.value != ReleaseManager.DB_ACTIVE);

        mLogger.fatal("run calling mReleaseManager.queryRunLevel");
        mReleaseManager.queryRunLevel(mRconId, buildFileContent);
        
        if ( buildFileContent.value.compareTo("") == 0)
        {
          mLogger.warn("run no longer configured 2");
          throw new ExitException();
        }
        
        mLogger.info("run consumed build files");

        if ( mUnitTest.compareTo("unit test consume build files") == 0 )
        {
          throw new ExitException();
        }

        // set CURRENT_BUILD_FILES to null
        mLogger.fatal("run calling mReleaseManager.clearBuildFile");
        mReleaseManager.clearBuildFile(mRconId);

        // check environment
        mLogger.warn("run checkEnvironment");
        mLogger.fatal("run calling checkEnvironment");
        checkEnvironment();
        mLogger.info("run checkEnvironment returned");
        
        mSleep = true;
        if ( buildFileContent.value.compareTo(mDummyBuildFileContent) != 0 )
        {
          // Start of a build cycle. Set new log file to capture entire build log
          flagStartBuildCycle();

          // deliver change to product baseline
          mLogger.warn("run deliverChange");
          mLogger.fatal("run calling setViewUp");
          setViewUp(buildFileContent.value, false);
          
          if ( mGbeGatherMetricsOnly != null )
          {
            // special for metrics
            // deliverChange on a benign target to get mReportingPackageName and mReportingPackageVersion set up
            // nb in the metrics gathering world the <rtagid>build.xml is provided by the master thread
            mLogger.fatal("run calling deliverChange on fullstart");
            deliverChange(null, "fullstart", false);
            
            String archive = Package.mGbeDpkg;
            
            if (archive != null)
            {
              String fs = System.getProperty( "file.separator" );
              String destination = archive + fs + mReportingPackageName + fs + mReportingPackageVersion;
              
              // do this for all unix based platforms
              new File( destination ).mkdirs();
              new File( destination, "built.sparc" ).createNewFile();
              new File( destination, "built.solaris10_sparc32" ).createNewFile();
              new File( destination, "built.solaris10_x86" ).createNewFile();
              new File( destination, "built.linux_i386" ).createNewFile();
            }
            
          }
          else
          {
            mLogger.fatal("run calling deliverChange - the actual build");
            deliverChange(null, null, false);
            mLogger.fatal("run calling deliverChange on AbtTearDown");
            deliverChange(null, "AbtTearDown", false);
          }
          
          if ( mReportingBuildFailureLogFile != null )
          {
            // tweak the build failure log file in the database
            Integer rtagId = mRtagId;
            
            // force exclusion by default
            int testBuildInstruction = 0;
            try
            {
              testBuildInstruction = Integer.parseInt( mReportingTestBuild );
            }
            catch( NumberFormatException nfe )
            {
            }
            mLogger.fatal("run calling excludeFromBuild");
            mReleaseManager.excludeFromBuild(mReportingPackageVersionId, mReportingPackageVersion, rtagId.toString(), null, null, mReportingBuildFailureLogFile, false, testBuildInstruction);
          }
          
          mLogger.info("run deliverChange returned");
          mSleep = false;
        }
        
      }
      catch( SQLException e )
      {
        // oracle connection issues        
         mLogger.warn("run oracle connection issues");
         mException = true;
      }
      catch( ExitException e )
      {
        mLogger.warn("run ExitException");
        exit = true;
      }
      catch( InterruptedException e )
      {
        mLogger.warn("run InterruptedException");
      }
      catch( Exception e )
      {
        mLogger.error("run indefinitePause " + e.toString());
        String cause = e.getMessage();
        if ( cause == null )
        {
          cause = e.toString();
        }
                
          try
          {
            // notify first
            // many reasons for indefinite pause, including database related, so do database last
            mRecoverable = false;
            
            if ( cause.compareTo(Package.mRecoverable) == 0 )
            {
              mRecoverable = true;
            }

            indefinitePause(rippleEngine, cause);
            mReleaseManager.indefinitePause();
            // DEVI 51366 force sleep at beginning of while loop
            mException = true;
          }
          catch( Exception f )
          {
            mLogger.error("run indefinitePause failed");
          }
        }
      }
    }

  /**returns 'S'
   */
  protected char getMode()
  {
    mLogger.debug("getMode");
    return 'S';
  }
}