using System; using Exortech.NetReflector; using ThoughtWorks.CruiseControl.Remote; namespace ThoughtWorks.CruiseControl.Core.Schedules { [Serializable] [ReflectorType("schedule")] public class Schedule : ISchedule { public const int Infinite = -1; public const int DefaultTimeOut = 60; private double _timeOut = DefaultTimeOut; private int _totalIterations = Infinite; private int _iterationsSoFar = 0; private bool _forceNextBuild = false; private DateTime _lastIntegrationCompleteTime = DateTime.MinValue; public Schedule() { } public Schedule(int timeout, int totalIterations) { _timeOut = timeout; _totalIterations = totalIterations; } /// /// Gets and sets the number of seconds between builds for which /// the project integrator should sleep. /// [ReflectorProperty("sleepSeconds")] public double SleepSeconds { get { return _timeOut; } set { _timeOut = value ; } } /// /// Gets and sets the total number of iterations this schedule will allow /// before stopping integration of the project. If this value is not /// specified, the number of iterations is not capped. /// [ReflectorProperty("iterations", Required=false)] public int TotalIterations { get { return _totalIterations; } set { _totalIterations = value; } } /// /// Gets and sets the schedule pauses for which builds do not occur. /// [ReflectorArray("pauseschedule", InstanceTypeKey="type", Required=false)] public IPauseSchedule[] SchedulePauses = new IPauseSchedule[0]; public void IntegrationCompleted() { _iterationsSoFar++; _lastIntegrationCompleteTime = DateTime.Now; } public BuildCondition ShouldRunIntegration() { if (ShouldStopIntegration()) return BuildCondition.NoBuild; if (_forceNextBuild) { _forceNextBuild = false; return BuildCondition.ForceBuild; } TimeSpan timeSinceLastBuild = DateTime.Now - _lastIntegrationCompleteTime; if (timeSinceLastBuild.TotalSeconds < SleepSeconds) return BuildCondition.NoBuild; // Check if the build is supposed to be paused right now. foreach (IPauseSchedule obj in SchedulePauses) { if (obj.IsPaused(DateTime.Now)) return BuildCondition.NoBuild; } return BuildCondition.IfModificationExists; } public bool ShouldStopIntegration() { return (_totalIterations != Infinite && _iterationsSoFar >= _totalIterations); } /// /// Forces to return true on its next /// invocation, regardless of the time since the previous build, etc... /// public void ForceBuild() { _forceNextBuild = true; } public int IterationsSoFar { get { return _iterationsSoFar; } } } }