func (s jobService) CanBuildBeScheduled(logger lager.Logger, build db.Build, buildPrep db.BuildPreparation, versions *algorithm.VersionsDB) ([]db.BuildInput, bool, string, error) { if build.Scheduled { return s.updateBuildPrepAndReturn(buildPrep, true, "build-scheduled") } paused, err := s.DB.IsPaused() if err != nil { return []db.BuildInput{}, false, "pause-pipeline-db-failed", err } if paused { buildPrep.PausedPipeline = db.BuildPreparationStatusBlocking return s.updateBuildPrepAndReturn(buildPrep, false, "pipeline-paused") } buildPrep.PausedPipeline = db.BuildPreparationStatusNotBlocking err = s.DB.UpdateBuildPreparation(buildPrep) if err != nil { return []db.BuildInput{}, false, "update-build-prep-db-failed-pipeline-not-paused", err } if s.DBJob.Paused { buildPrep.PausedJob = db.BuildPreparationStatusBlocking return s.updateBuildPrepAndReturn(buildPrep, false, "job-paused") } buildPrep.PausedJob = db.BuildPreparationStatusNotBlocking err = s.DB.UpdateBuildPreparation(buildPrep) if err != nil { return []db.BuildInput{}, false, "update-build-prep-db-failed-job-not-paused", err } if build.Status != db.StatusPending { return []db.BuildInput{}, false, "build-not-pending", nil } buildInputs, buildPrep, message, err := s.getBuildInputs(logger, build, buildPrep, versions) if err != nil || message != "" { return []db.BuildInput{}, false, message, err } buildPrep.MaxRunningBuilds = db.BuildPreparationStatusBlocking err = s.DB.UpdateBuildPreparation(buildPrep) if err != nil { return []db.BuildInput{}, false, "update-build-prep-db-failed-pipeline-not-paused", err } maxInFlight := s.JobConfig.MaxInFlight() if maxInFlight > 0 { builds, err := s.DB.GetRunningBuildsBySerialGroup(s.DBJob.Name, s.JobConfig.GetSerialGroups()) if err != nil { return []db.BuildInput{}, false, "db-failed", err } if len(builds) >= maxInFlight { buildPrep.MaxRunningBuilds = db.BuildPreparationStatusBlocking return s.updateBuildPrepAndReturn(buildPrep, false, "max-in-flight-reached") } nextMostPendingBuild, found, err := s.DB.GetNextPendingBuildBySerialGroup(s.DBJob.Name, s.JobConfig.GetSerialGroups()) if err != nil { return []db.BuildInput{}, false, "db-failed", err } if !found { return []db.BuildInput{}, false, "no-pending-build", nil } if nextMostPendingBuild.ID != build.ID { return []db.BuildInput{}, false, "not-next-most-pending", nil } } buildPrep.MaxRunningBuilds = db.BuildPreparationStatusNotBlocking err = s.DB.UpdateBuildPreparation(buildPrep) if err != nil { return []db.BuildInput{}, false, "update-build-prep-db-failed-not-max-running-builds", err } return buildInputs, true, "can-be-scheduled", nil }