Exemple #1
0
 public BuilderContext(string buildPath, string buildProfile, FileVersionTracker inputHashes, BuildParameterCollection parameters, int maxParallelProcess, string slaveBuilderPath)
 {
     BuildPath            = buildPath;
     BuildProfile         = buildProfile;
     InputHashes          = inputHashes;
     Parameters           = parameters;
     SlaveBuilderPath     = slaveBuilderPath;
     MaxParallelProcesses = maxParallelProcess;
 }
Exemple #2
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public BuildResultCode Run(Mode mode, bool writeIndexFile = true, bool enableMonitor = true)
        {
            // When we setup the database ourself we have to take responsibility to close it after
            var shouldCloseDatabase = ObjectDatabase == null;

            OpenObjectDatabase(buildPath, indexName);

            PreRun();

            runMode = mode;

            if (IsRunning)
            {
                throw new InvalidOperationException("An instance of this Builder is already running.");
            }

            // reset build cache from previous build run
            var parameters = new BuildParameterCollection();

            cancellationTokenSource = new CancellationTokenSource();
            Cancelled = false;
            IsRunning = true;
            DisableCompressionIds.Clear();

            // Reseting result map
            var inputHashes = FileVersionTracker.GetDefault();

            {
                var builderContext = new BuilderContext(buildPath, buildProfile, inputHashes, parameters, MaxParallelProcesses, SlaveBuilderPath);

                resultMap = ObjectDatabase;

                scheduler = new Scheduler();
                if (enableMonitor)
                {
                    threadMonitors.Add(new BuildThreadMonitor(scheduler, BuilderId));
                    foreach (var monitorPipeName in MonitorPipeNames)
                    {
                        threadMonitors.Add(new BuildThreadMonitor(scheduler, BuilderId, monitorPipeName));
                    }

                    foreach (var threadMonitor in threadMonitors)
                    {
                        threadMonitor.Start();
                    }
                }

                // Schedule the build
                ScheduleBuildStep(builderContext, null, Root, InitialVariables);

                // Create threads
                var threads = Enumerable.Range(0, ThreadCount).Select(x => new Thread(SafeAction.Wrap(RunUntilEnd))
                {
                    IsBackground = true
                }).ToArray();

                // Start threads
                int threadId = 0;
                foreach (var thread in threads)
                {
                    thread.Name = (BuilderName ?? "Builder") + " worker thread " + (++threadId);
                    thread.Start();
                }

                // Wait for all threads to finish
                foreach (var thread in threads)
                {
                    thread.Join();
                }

                foreach (var threadMonitor in threadMonitors)
                {
                    threadMonitor.Finish();
                }

                foreach (var threadMonitor in threadMonitors)
                {
                    threadMonitor.Join();
                }
            }

            threadMonitors.Clear();
            BuildResultCode result;

            if (runMode == Mode.Build)
            {
                if (cancellationTokenSource.IsCancellationRequested)
                {
                    Logger.Error("Build cancelled.");
                    result = BuildResultCode.Cancelled;
                }
                else if (stepCounter.Get(ResultStatus.Failed) > 0 || stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed) > 0)
                {
                    Logger.Error("Build finished in {0} steps. Command results: {1} succeeded, {2} up-to-date, {3} failed, {4} not triggered due to previous failure.",
                                 stepCounter.Total, stepCounter.Get(ResultStatus.Successful), stepCounter.Get(ResultStatus.NotTriggeredWasSuccessful),
                                 stepCounter.Get(ResultStatus.Failed), stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed));

                    Logger.Error("Build failed.");
                    result = BuildResultCode.BuildError;
                }
                else
                {
                    Logger.Info("Build finished in {0} steps. Command results: {1} succeeded, {2} up-to-date, {3} failed, {4} not triggered due to previous failure.",
                                stepCounter.Total, stepCounter.Get(ResultStatus.Successful), stepCounter.Get(ResultStatus.NotTriggeredWasSuccessful),
                                stepCounter.Get(ResultStatus.Failed), stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed));

                    Logger.Info("Build is successful.");
                    result = BuildResultCode.Successful;
                }
            }
            else
            {
                string modeName;
                switch (runMode)
                {
                case Mode.Clean:
                    modeName = "Clean";
                    break;

                case Mode.CleanAndDelete:
                    modeName = "Clean-and-delete";
                    break;

                default:
                    throw new InvalidOperationException("Builder executed in unknown mode.");
                }

                if (cancellationTokenSource.IsCancellationRequested)
                {
                    Logger.Error(modeName + " has been cancelled.");
                    result = BuildResultCode.Cancelled;
                }
                else if (stepCounter.Get(ResultStatus.Failed) > 0 || stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed) > 0)
                {
                    Logger.Error(modeName + " has failed.");
                    result = BuildResultCode.BuildError;
                }
                else
                {
                    Logger.Error(modeName + " has been successfully completed.");
                    result = BuildResultCode.Successful;
                }
            }
            scheduler = null;
            resultMap = null;
            IsRunning = false;

            if (shouldCloseDatabase)
            {
                CloseObjectDatabase();
            }

            return(result);
        }
Exemple #3
0
        /// <summary>
        /// Runs this instance.
        /// </summary>
        public BuildResultCode Run(Mode mode, bool writeIndexFile = true, bool enableMonitor = true)
        {
            runMode = mode;

            if (IsRunning)
            {
                throw new InvalidOperationException("An instance of this Builder is already running.");
            }

            // reset build cache from previous build run
            var parameters = new BuildParameterCollection();

            cancellationTokenSource = new CancellationTokenSource();
            Cancelled = false;
            IsRunning = true;
            DisableCompressionIds.Clear();

            // Reseting result map
            var inputHashes = FileVersionTracker.GetDefault();

            {
                var builderContext = new BuilderContext(buildPath, buildProfile, inputHashes, parameters, MaxParallelProcesses, SlaveBuilderPath);
                if (!string.IsNullOrWhiteSpace(MetadataDatabaseDirectory))
                {
                    var metadataProvider = new QueryMetadataProvider();
                    if (metadataProvider.Open(Path.Combine(MetadataDatabaseDirectory, QueryMetadataProvider.DefaultDatabaseFilename), false))
                    {
                        builderContext.MetadataProvider = metadataProvider;
                    }
                }

                resultMap = IndexFileCommand.ObjectDatabase;

                scheduler = new Scheduler();
                if (enableMonitor)
                {
                    threadMonitors.Add(new BuildThreadMonitor(scheduler, BuilderId));
                    foreach (var monitorPipeName in MonitorPipeNames)
                    {
                        threadMonitors.Add(new BuildThreadMonitor(scheduler, BuilderId, monitorPipeName));
                    }

                    foreach (var threadMonitor in threadMonitors)
                    {
                        threadMonitor.Start();
                    }
                }

                ScheduleBuildStep(builderContext, null, Root, InitialVariables);

                // Create threads
                var threads = Enumerable.Range(0, ThreadCount).Select(x => new Thread(SafeAction.Wrap(RunUntilEnd))
                {
                    IsBackground = true
                }).ToArray();

                // Start threads
                int threadId = 0;
                foreach (var thread in threads)
                {
                    thread.Name = "Builder thread " + (++threadId);
                    thread.Start();
                }

                // Wait for all threads to finish
                foreach (var thread in threads)
                {
                    thread.Join();
                }

                foreach (var threadMonitor in threadMonitors)
                {
                    threadMonitor.Finish();
                }

                foreach (var threadMonitor in threadMonitors)
                {
                    threadMonitor.Join();
                }
            }

            threadMonitors.Clear();
            BuildResultCode result;

            if (runMode == Mode.Build)
            {
                Logger.Info("");
                if (cancellationTokenSource.IsCancellationRequested)
                {
                    Logger.Error("Build cancelled.");
                    result = BuildResultCode.Cancelled;
                }
                else if (stepCounter.Get(ResultStatus.Failed) > 0 || stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed) > 0)
                {
                    Logger.Error("Build finished in {0} steps. Command results: {1} succeeded, {2} up-to-date, {3} failed, {4} not triggered due to previous failure.",
                                 stepCounter.Total, stepCounter.Get(ResultStatus.Successful), stepCounter.Get(ResultStatus.NotTriggeredWasSuccessful),
                                 stepCounter.Get(ResultStatus.Failed), stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed));

                    Logger.Error("Build failed.");
                    result = BuildResultCode.BuildError;
                }
                else
                {
                    Logger.Info("Build finished in {0} steps. Command results: {1} succeeded, {2} up-to-date, {3} failed, {4} not triggered due to previous failure.",
                                stepCounter.Total, stepCounter.Get(ResultStatus.Successful), stepCounter.Get(ResultStatus.NotTriggeredWasSuccessful),
                                stepCounter.Get(ResultStatus.Failed), stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed));

                    Logger.Info("Build is successful.");
                    result = BuildResultCode.Successful;
                }
            }
            else
            {
                // Clean input hashes file
                if (VirtualFileSystem.FileExists(InputHashesFileFullPath))
                {
                    try
                    {
                        VirtualFileSystem.FileDelete(InputHashesFileFullPath);
                    }
                    catch (IOException)
                    {
                        return(BuildResultCode.BuildError);
                    }
                }
                string modeName;
                switch (runMode)
                {
                case Mode.Clean:
                    modeName = "Clean";
                    break;

                case Mode.CleanAndDelete:
                    modeName = "Clean-and-delete";
                    break;

                default:
                    throw new InvalidOperationException("Builder executed in unknown mode.");
                }

                if (cancellationTokenSource.IsCancellationRequested)
                {
                    Logger.Error(modeName + " has been cancelled.");
                    result = BuildResultCode.Cancelled;
                }
                else if (stepCounter.Get(ResultStatus.Failed) > 0 || stepCounter.Get(ResultStatus.NotTriggeredPrerequisiteFailed) > 0)
                {
                    Logger.Error(modeName + " has failed.");
                    result = BuildResultCode.BuildError;
                }
                else
                {
                    Logger.Error(modeName + " has been successfully completed.");
                    result = BuildResultCode.Successful;
                }
            }
            scheduler = null;
            resultMap = null;
            IsRunning = false;

            return(result);
        }
Exemple #4
0
 protected CommandContextBase(Command command, BuilderContext builderContext)
 {
     CurrentCommand  = command;
     BuildParameters = builderContext.Parameters;
     ResultEntry     = new CommandResultEntry();
 }
        public static BuildResultCode BuildSlave(BuilderOptions options)
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(options.BuildDirectory);

            PrepareDatabases(options);

            try
            {
                VirtualFileSystem.CreateDirectory("/data/");
                VirtualFileSystem.CreateDirectory("/data/db/");
            }
            catch (Exception)
            {
                throw new OptionException("Invalid Build database path", "database");
            }

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0)
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(options.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string      buildPath   = options.BuildDirectory;
                Logger      logger      = options.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();
                    BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters();

                    // Run command
                    var inputHashes    = new DictionaryStore <InputVersionKey, ObjectId>(VirtualFileSystem.OpenStream("/data/db/InputHashes", VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite));
                    var builderContext = new BuilderContext(buildPath, inputHashes, parameters, 0, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    options.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
Exemple #6
0
 public ProcessBuilderRemote(LocalCommandContext commandContext, Command remoteCommand, BuildParameterCollection buildParameters)
 {
     this.commandContext  = commandContext;
     this.remoteCommand   = remoteCommand;
     this.buildParameters = buildParameters;
 }