예제 #1
0
        public override async Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            var buildStepsToWait = new List <BuildStep>();

            // Process prerequisites build steps first
            if (PrerequisiteSteps.Count > 0)
            {
                await CompleteCommands(executeContext, PrerequisiteSteps.ToList());
            }

            foreach (var child in Steps)
            {
                // Wait for all the tasks before the WaitBuildStep to be finished
                if (child is WaitBuildStep)
                {
                    await CompleteCommands(executeContext, buildStepsToWait);
                }
                else
                {
                    executeContext.ScheduleBuildStep(child);
                    buildStepsToWait.Add(child);
                }

                executedSteps.Add(child);
            }

            await CompleteCommands(executeContext, buildStepsToWait);

            return(ComputeResultStatusFromExecutedSteps());
        }
예제 #2
0
        public override async Task<ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            var buildStepsToWait = new List<BuildStep>();

            // Process prerequisites build steps first
            if (PrerequisiteSteps.Count > 0)
                await CompleteCommands(executeContext, PrerequisiteSteps.ToList());

            foreach (var child in Steps)
            {
                // Wait for all the tasks before the WaitBuildStep to be finished
                if (child is WaitBuildStep)
                {
                    await CompleteCommands(executeContext, buildStepsToWait);
                }
                else
                {
                    executeContext.ScheduleBuildStep(child);
                    buildStepsToWait.Add(child);
                }

                executedSteps.Add(child);
            }

            await CompleteCommands(executeContext, buildStepsToWait);
            
            return ComputeResultStatusFromExecutedSteps();
        }
예제 #3
0
        public async override Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            var buildStepsToWait = new List <BuildStep>();

            while (true)
            {
                // interrupt the build if cancellation is required.
                if (executeContext.CancellationTokenSource.Token.IsCancellationRequested)
                {
                    return(ResultStatus.Cancelled);
                }

                // Clean completed build steps
                for (int index = buildStepsToWait.Count - 1; index >= 0; index--)
                {
                    var buildStepToWait = buildStepsToWait[index];
                    if (buildStepToWait.Processed)
                    {
                        buildStepsToWait.RemoveAt(index);
                    }
                }

                // wait for a task to complete
                if (buildStepsToWait.Count >= MaxParallelSteps)
                {
                    await CompleteOneBuildStep(executeContext, buildStepsToWait);
                }

                // Should we check for all tasks or only high priority tasks? (priority < 0)
                bool checkOnlyForHighPriorityTasks = buildStepsToWait.Count >= MaxParallelSteps;

                // Transform item into build step
                var buildStep = buildStepProvider.GetNextBuildStep(checkOnlyForHighPriorityTasks ? -1 : int.MaxValue);

                // No job => passively wait
                if (buildStep == null)
                {
                    newWorkAvailable.WaitOne();
                    continue;
                }

                // Safeguard if the provided build step is already processed
                if (buildStep.Processed)
                {
                    continue;
                }

                if (buildStep is WaitBuildStep)
                {
                    throw new InvalidOperationException("WaitBuildStep are not supported as direct child of DynamicBuildStep");
                }

                // Schedule build step
                executeContext.ScheduleBuildStep(buildStep);
                buildStepsToWait.Add(buildStep);
            }
        }
예제 #4
0
        internal async Task <ResultStatus> SpawnCommand(Command command, IExecuteContext executeContext)
        {
            var spawnedStep = new CommandBuildStep(command);

            SpawnedStepsList.Add(spawnedStep);

            executeContext.ScheduleBuildStep(spawnedStep);
            var resultStatus = (await spawnedStep.ExecutedAsync()).Status;

            return(resultStatus);
        }
예제 #5
0
        public override async Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            Steps = new List <BuildStep>();
            var files = Enumerable.Empty <string>();

            foreach (string pattern in SearchPattern)
            {
                string path        = Path.GetDirectoryName(pattern);
                string filePattern = Path.GetFileName(pattern);
                if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(filePattern))
                {
                    files = files.Concat(Directory.EnumerateFiles(path, filePattern));
                }
                else
                {
                    files = files.Concat(Directory.EnumerateFiles(pattern));
                }
            }

            var excludes = Enumerable.Empty <string>();

            foreach (string pattern in ExcludePattern)
            {
                string path        = Path.GetDirectoryName(pattern);
                string filePattern = Path.GetFileName(pattern);
                if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(filePattern))
                {
                    excludes = excludes.Concat(Directory.EnumerateFiles(path, filePattern));
                }
                else
                {
                    excludes = excludes.Concat(Directory.EnumerateFiles(pattern));
                }
            }

            var buildStepToWait = new List <BuildStep>();

            lock (Files)
            {
                Files = files.Where(x => !excludes.Contains(x));
                foreach (string file in Files)
                {
                    executeContext.Variables["FILE"] = file;
                    var fileBuildStep = Template.Clone();
                    ((List <BuildStep>)Steps).Add(fileBuildStep);
                    buildStepToWait.Add(fileBuildStep);
                    executeContext.ScheduleBuildStep(fileBuildStep);
                }
            }

            await CompleteCommands(executeContext, buildStepToWait);

            return(ResultStatus.Successful);
        }
예제 #6
0
        public async override Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            var buildStepsToWait = new List <BuildStep>();

            while (true)
            {
                // interrupt the build if cancellation is required.
                if (executeContext.CancellationTokenSource.Token.IsCancellationRequested)
                {
                    return(ResultStatus.Cancelled);
                }

                // wait for a task to complete
                if (buildStepsToWait.Count >= MaxParallelism)
                {
                    await CompleteOneBuildStep(executeContext, buildStepsToWait);
                }

                // Transform item into build step
                var buildStep = buildStepProvider.GetNextBuildStep();

                // No job => passively wait
                if (buildStep == null)
                {
                    newWorkAvailable.WaitOne();

                    continue;
                }

                // Safeguard if the provided build step is already processed
                if (buildStep.Processed)
                {
                    continue;
                }

                if (buildStep is WaitBuildStep)
                {
                    // wait for all the task in execution to complete
                    while (buildStepsToWait.Count > 0)
                    {
                        await CompleteOneBuildStep(executeContext, buildStepsToWait);
                    }

                    continue;
                }

                // Schedule build step
                executeContext.ScheduleBuildStep(buildStep);
                buildStepsToWait.Add(buildStep);
            }
        }
예제 #7
0
        public async override Task<ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            var buildStepsToWait = new List<BuildStep>();

            while (true)
            {
                // interrupt the build if cancellation is required.
                if (executeContext.CancellationTokenSource.Token.IsCancellationRequested)
                    return ResultStatus.Cancelled;

                // wait for a task to complete
                if (buildStepsToWait.Count >= MaxParallelSteps)
                    await CompleteOneBuildStep(executeContext, buildStepsToWait);

                // Should we check for all tasks or only high priority tasks? (priority < 0)
                bool checkOnlyForHighPriorityTasks = buildStepsToWait.Count >= MaxParallelSteps;

                // Transform item into build step
                var buildStep = buildStepProvider.GetNextBuildStep(checkOnlyForHighPriorityTasks ? -1 : int.MaxValue);

                // No job => passively wait
                if (buildStep == null)
                {
                    newWorkAvailable.WaitOne();
                    continue;
                }

                // Safeguard if the provided build step is already processed
                if(buildStep.Processed)
                    continue;

                if (buildStep is WaitBuildStep)
                {
                    throw new InvalidOperationException("WaitBuildStep are not supported as direct child of DynamicBuildStep");
                }

                // Schedule build step
                executeContext.ScheduleBuildStep(buildStep);
                buildStepsToWait.Add(buildStep);
            }
        }
        public override async Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            Steps = new List <BuildStep>();

            var urls = Enumerable.Empty <string>();

            BuildStep parentList = Parent;

            while (!(parentList is ListBuildStep))
            {
                parentList = parentList.Parent;
            }

            var parentListBuildStep = (ListBuildStep)parentList;


            foreach (string tag in SearchTags)
            {
                urls = urls.Concat(parentListBuildStep.OutputObjects.Where(x => x.Value.Tags.Contains(tag)).Select(x => x.Key.ToString()));
            }

            var buildStepToWait = new List <BuildStep>();

            lock (Urls)
            {
                Urls = urls;
                foreach (string url in Urls)
                {
                    executeContext.Variables["URL"] = url;
                    var fileBuildStep = Template.Clone();
                    ((List <BuildStep>)Steps).Add(fileBuildStep);
                    buildStepToWait.Add(fileBuildStep);
                    executeContext.ScheduleBuildStep(fileBuildStep);
                }
            }

            await CompleteCommands(executeContext, buildStepToWait);

            return(ResultStatus.Successful);
        }
        public override async Task<ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            Steps = new List<BuildStep>();

            var urls = Enumerable.Empty<string>();

            BuildStep parentList = Parent;
            while (!(parentList is ListBuildStep))
            {
                parentList = parentList.Parent;
            }

            var parentListBuildStep = (ListBuildStep)parentList;


            foreach (string tag in SearchTags)
            {
                urls = urls.Concat(parentListBuildStep.OutputObjects.Where(x => x.Value.Tags.Contains(tag)).Select(x => x.Key.ToString()));
            }

            var buildStepToWait = new List<BuildStep>();

            lock (Urls)
            {
                Urls = urls;
                foreach (string url in Urls)
                {
                    executeContext.Variables["URL"] = url;
                    var fileBuildStep = Template.Clone();
                    ((List<BuildStep>)Steps).Add(fileBuildStep);
                    buildStepToWait.Add(fileBuildStep);
                    executeContext.ScheduleBuildStep(fileBuildStep);
                }
            }

            await CompleteCommands(executeContext, buildStepToWait);

            return ResultStatus.Successful;
        }
예제 #10
0
        public override async Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            ListStore <CommandResultEntry> commandResultEntries;

            // Prevent several command build step to evaluate wheither they should start at the same time. This increase the efficiency of the builder by avoiding the same command to be executed several time in parallel
            // NOTE: Careful here, there's no try/finally block around the monitor Enter/Exit, so no non-fatal exception is allowed!
            Monitor.Enter(executeContext);
            bool monitorExited = false;
            var  status        = ResultStatus.NotProcessed;
            // if any external input has changed since the last execution (or if we don't have a successful execution in cache, trigger the command
            CommandResultEntry matchingResult = null;

            try
            {
                ObjectId commandHash;
                {
                    // try to retrieve result from one of the object store
                    commandHash = Command.ComputeCommandHash(executeContext);
                    // Early exit if the hash of the command failed
                    if (commandHash == ObjectId.Empty)
                    {
                        return(ResultStatus.Failed);
                    }

                    var commandResultsFileStream = executeContext.ResultMap.OpenStream(commandHash, VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite);
                    commandResultEntries = new ListStore <CommandResultEntry>(commandResultsFileStream)
                    {
                        AutoLoadNewValues = false
                    };
                    commandResultEntries.LoadNewValues();
                }

                if (ShouldExecute(executeContext, commandResultEntries.GetValues(), commandHash, out matchingResult))
                {
                    CommandBuildStep stepInProgress = executeContext.IsCommandCurrentlyRunning(commandHash);
                    if (stepInProgress != null)
                    {
                        Monitor.Exit(executeContext);
                        monitorExited = true;
                        executeContext.Logger.Debug("Command {0} delayed because it is currently running...", Command.ToString());
                        status         = (await stepInProgress.ExecutedAsync()).Status;
                        matchingResult = stepInProgress.Result;
                    }
                    else
                    {
                        executeContext.NotifyCommandBuildStepStarted(this, commandHash);
                        Monitor.Exit(executeContext);
                        monitorExited = true;

                        executeContext.Logger.Debug("Command {0} scheduled...", Command.ToString());

                        // Register the cancel callback
                        var cancellationTokenSource = executeContext.CancellationTokenSource;
                        cancellationTokenSource.Token.Register(x => ((Command)x).Cancel(), Command);

                        Command.CancellationToken = cancellationTokenSource.Token;

                        try
                        {
                            status = await StartCommand(executeContext, commandResultEntries, builderContext);
                        }
                        finally
                        {
                            // Restore cancellation token (to avoid memory leak due to previous CancellationToken.Register
                            Command.CancellationToken = CancellationToken.None;
                        }

                        executeContext.NotifyCommandBuildStepFinished(this, commandHash);
                    }
                }
            }
            finally
            {
                if (!monitorExited)
                {
                    Monitor.Exit(executeContext);
                }
            }

            // The command has not been executed
            if (matchingResult != null)
            {
                using (commandResultEntries)
                {
                    // Replicate triggered builds
                    Debug.Assert(SpawnedStepsList.Count == 0);

                    foreach (Command spawnedCommand in matchingResult.SpawnedCommands)
                    {
                        var spawnedStep = new CommandBuildStep(spawnedCommand);
                        SpawnedStepsList.Add(spawnedStep);
                        executeContext.ScheduleBuildStep(spawnedStep);
                    }

                    // Re-output command log messages
                    foreach (var message in matchingResult.LogMessages)
                    {
                        executeContext.Logger.Log(message);
                    }

                    // Wait for all build steps to complete.
                    // TODO: Ideally, we should store and replicate the behavior of the command that spawned it
                    // (wait if it used ScheduleAndExecute, don't wait if it used RegisterSpawnedCommandWithoutScheduling)
                    await Task.WhenAll(SpawnedSteps.Select(x => x.ExecutedAsync()));

                    status = ResultStatus.NotTriggeredWasSuccessful;
                    RegisterCommandResult(commandResultEntries, matchingResult, status);
                }
            }


            return(status);
        }
예제 #11
0
        internal async Task<ResultStatus> SpawnCommand(Command command, IExecuteContext executeContext)
        {
            var spawnedStep = new CommandBuildStep(command);
            SpawnedStepsList.Add(spawnedStep);

            executeContext.ScheduleBuildStep(spawnedStep);
            var resultStatus = (await spawnedStep.ExecutedAsync()).Status;

            return resultStatus;
        }
예제 #12
0
        public override async Task<ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            ListStore<CommandResultEntry> commandResultEntries;

            // Prevent several command build step to evaluate wheither they should start at the same time. This increase the efficiency of the builder by avoiding the same command to be executed several time in parallel
            // NOTE: Careful here, there's no try/finally block around the monitor Enter/Exit, so no non-fatal exception is allowed!
            Monitor.Enter(executeContext);
            bool monitorExited = false;
            var status = ResultStatus.NotProcessed;
            // if any external input has changed since the last execution (or if we don't have a successful execution in cache, trigger the command
            CommandResultEntry matchingResult = null;

            try
            {
                ObjectId commandHash;
                {
                    // try to retrieve result from one of the object store
                    commandHash = Command.ComputeCommandHash(executeContext);
                    // Early exit if the hash of the command failed
                    if (commandHash == ObjectId.Empty)
                    {
                        return ResultStatus.Failed;
                    }

                    var commandResultsFileStream = executeContext.ResultMap.OpenStream(commandHash, VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite);
                    commandResultEntries = new ListStore<CommandResultEntry>(commandResultsFileStream) { AutoLoadNewValues = false };
                    commandResultEntries.LoadNewValues();
                }

                if (ShouldExecute(executeContext, commandResultEntries.GetValues(), commandHash, out matchingResult))
                {
                    CommandBuildStep stepInProgress = executeContext.IsCommandCurrentlyRunning(commandHash);
                    if (stepInProgress != null)
                    {
                        Monitor.Exit(executeContext);
                        monitorExited = true;
                        executeContext.Logger.Debug("Command {0} delayed because it is currently running...", Command.ToString());
                        status = (await stepInProgress.ExecutedAsync()).Status;
                        matchingResult = stepInProgress.Result;
                    }
                    else
                    {
                        executeContext.NotifyCommandBuildStepStarted(this, commandHash);
                        Monitor.Exit(executeContext);
                        monitorExited = true;

                        executeContext.Logger.Debug("Command {0} scheduled...", Command.ToString());

                        status = await StartCommand(executeContext, commandResultEntries, builderContext);
                        executeContext.NotifyCommandBuildStepFinished(this, commandHash);
                    }
                }
            }
            finally
            {
                if (!monitorExited)
                {
                    Monitor.Exit(executeContext);
                }
            }

            // The command has not been executed
            if (matchingResult != null)
            {
                using (commandResultEntries)
                {
                    // Replicate triggered builds
                    Debug.Assert(SpawnedStepsList.Count == 0);

                    foreach (Command spawnedCommand in matchingResult.SpawnedCommands)
                    {
                        var spawnedStep = new CommandBuildStep(spawnedCommand);
                        SpawnedStepsList.Add(spawnedStep);
                        executeContext.ScheduleBuildStep(spawnedStep);
                    }

                    // Re-output command log messages
                    foreach (var message in matchingResult.LogMessages)
                    {
                        executeContext.Logger.Log(message);
                    }

                    // Wait for all build steps to complete.
                    // TODO: Ideally, we should store and replicate the behavior of the command that spawned it
                    // (wait if it used ScheduleAndExecute, don't wait if it used RegisterSpawnedCommandWithoutScheduling)
                    await Task.WhenAll(SpawnedSteps.Select(x => x.ExecutedAsync()));

                    status = ResultStatus.NotTriggeredWasSuccessful;
                    RegisterCommandResult(commandResultEntries, matchingResult, status);
                }
            }


            return status;
        }
예제 #13
0
        public override async Task <ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            ListStore <CommandResultEntry> commandResultEntries;

            // Prevent several command build step to evaluate wheither they should start at the same time. This increase the efficiency of the builder by avoiding the same command to be executed several time in parallel
            // NOTE: Careful here, there's no try/finally block around the monitor Enter/Exit, so no non-fatal exception is allowed!
            Monitor.Enter(executeContext);

            ObjectId commandHash;
            //await Task.Factory.StartNew(() =>
            {
                // try to retrieve result from one of the object store
                commandHash = Command.ComputeCommandHash(executeContext);
                var commandResultsFileStream = executeContext.ResultMap.OpenStream(commandHash, VirtualFileMode.OpenOrCreate, VirtualFileAccess.ReadWrite, VirtualFileShare.ReadWrite);
                commandResultEntries = new ListStore <CommandResultEntry>(commandResultsFileStream)
                {
                    AutoLoadNewValues = false
                };
                commandResultEntries.LoadNewValues();
            }
            //);

            // if any external input has changed since the last execution (or if we don't have a successful execution in cache, trigger the command
            CommandResultEntry matchingResult;
            var status = ResultStatus.NotProcessed;

            if (ShouldExecute(executeContext, commandResultEntries.GetValues(), commandHash, out matchingResult))
            {
                CommandBuildStep stepInProgress = executeContext.IsCommandCurrentlyRunning(commandHash);
                if (stepInProgress != null)
                {
                    Monitor.Exit(executeContext);
                    executeContext.Logger.Debug("Command {0} delayed because it is currently running...", Command.ToString());
                    status         = (await stepInProgress.ExecutedAsync()).Status;
                    matchingResult = stepInProgress.Result;
                }
                else
                {
                    executeContext.NotifyCommandBuildStepStarted(this, commandHash);
                    Monitor.Exit(executeContext);

                    executeContext.Logger.Debug("Command {0} scheduled...", Command.ToString());

                    status = await StartCommand(executeContext, commandResultEntries, builderContext);

                    executeContext.NotifyCommandBuildStepFinished(this, commandHash);
                }
            }
            else
            {
                Monitor.Exit(executeContext);
            }

            // The command has not been executed
            if (matchingResult != null)
            {
                using (commandResultEntries)
                {
                    // the command was not started because it is already up-to-date (retrieved from cache and no change in external files since last execution)
                    executeContext.Logger.Verbose("Command {0} is up-to-date, skipping...", Command.ToString());

                    // Replicate triggered builds
                    Debug.Assert(SpawnedStepsList.Count == 0);

                    foreach (Command spawnedCommand in matchingResult.SpawnedCommands)
                    {
                        var spawnedStep = new CommandBuildStep(spawnedCommand);
                        SpawnedStepsList.Add(spawnedStep);
                        executeContext.ScheduleBuildStep(spawnedStep);
                    }

                    // Wait for all build steps to complete.
                    // TODO: Ideally, we should store and replicate the behavior of the command that spawned it
                    // (wait if it used ScheduleAndExecute, don't wait if it used RegisterSpawnedCommandWithoutScheduling)
                    await Task.WhenAll(SpawnedSteps.Select(x => x.ExecutedAsync()));

                    status = ResultStatus.NotTriggeredWasSuccessful;

                    RegisterCommandResult(commandResultEntries, matchingResult, status);
                }
            }

            return(status);
        }
예제 #14
0
        public override async Task<ResultStatus> Execute(IExecuteContext executeContext, BuilderContext builderContext)
        {
            Steps = new List<BuildStep>();
            var files = Enumerable.Empty<string>();

            foreach (string pattern in SearchPattern)
            {
                string path = Path.GetDirectoryName(pattern);
                string filePattern = Path.GetFileName(pattern);
                if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(filePattern))
                {
                    files = files.Concat(Directory.EnumerateFiles(path, filePattern));
                }
                else
                {
                    files = files.Concat(Directory.EnumerateFiles(pattern));
                }
            }

            var excludes = Enumerable.Empty<string>();

            foreach (string pattern in ExcludePattern)
            {
                string path = Path.GetDirectoryName(pattern);
                string filePattern = Path.GetFileName(pattern);
                if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(filePattern))
                {
                    excludes = excludes.Concat(Directory.EnumerateFiles(path, filePattern));
                }
                else
                {
                    excludes = excludes.Concat(Directory.EnumerateFiles(pattern));
                }
            }

            var buildStepToWait = new List<BuildStep>();
            
            lock (Files)
            {
                Files = files.Where(x => !excludes.Contains(x));
                foreach (string file in Files)
                {
                    executeContext.Variables["FILE"] = file;
                    var fileBuildStep = Template.Clone();
                    ((List<BuildStep>)Steps).Add(fileBuildStep);
                    buildStepToWait.Add(fileBuildStep);
                    executeContext.ScheduleBuildStep(fileBuildStep);
                }
            }

            await CompleteCommands(executeContext, buildStepToWait);

            return ResultStatus.Successful;
        }