func (c *Controller) terminateDupes(pjs []prowapi.ProwJob, jbs map[string]Build) error {
	// "job org/repo#number" -> newest job
	dupes := make(map[string]int)
	for i, pj := range pjs {
		if pj.Complete() || pj.Spec.Type != prowapi.PresubmitJob {
			continue
		}
		n := fmt.Sprintf("%s %s/%s#%d", pj.Spec.Job, pj.Spec.Refs.Org, pj.Spec.Refs.Repo, pj.Spec.Refs.Pulls[0].Number)
		prev, ok := dupes[n]
		if !ok {
			dupes[n] = i
			continue
		}
		cancelIndex := i
		if (&pjs[prev].Status.StartTime).Before(&pj.Status.StartTime) {
			cancelIndex = prev
			dupes[n] = i
		}
		toCancel := pjs[cancelIndex]
		// Allow aborting presubmit jobs for commits that have been superseded by
		// newer commits in GitHub pull requests.
		if c.config().AllowCancellations {
			build, buildExists := jbs[toCancel.ObjectMeta.Name]
			// Avoid cancelling enqueued builds.
			if buildExists && build.IsEnqueued() {
				continue
			}
			// Otherwise, abort it.
			if buildExists {
				if err := c.jc.Abort(getJobName(&toCancel.Spec), &build); err != nil {
					c.log.WithError(err).WithFields(pjutil.ProwJobFields(&toCancel)).Warn("Cannot cancel Jenkins build")
				}
			}
		}
		toCancel.SetComplete()
		prevState := toCancel.Status.State
		toCancel.Status.State = prowapi.AbortedState
		c.log.WithFields(pjutil.ProwJobFields(&toCancel)).
			WithField("from", prevState).
			WithField("to", toCancel.Status.State).Info("Transitioning states.")
		npj, err := c.prowJobClient.Update(&toCancel)
		if err != nil {
			return err
		}
		pjs[cancelIndex] = *npj
	}
	return nil
}
func (c *Controller) terminateDupes(pjs []prowapi.ProwJob, jbs map[string]Build) error {
	
	dupes := make(map[string]int)
	for i, pj := range pjs {
		if pj.Complete() || pj.Spec.Type != prowapi.PresubmitJob {
			continue
		}
		n := fmt.Sprintf("%s %s/%s#%d", pj.Spec.Job, pj.Spec.Refs.Org, pj.Spec.Refs.Repo, pj.Spec.Refs.Pulls[0].Number)
		prev, ok := dupes[n]
		if !ok {
			dupes[n] = i
			continue
		}
		cancelIndex := i
		if (&pjs[prev].Status.StartTime).Before(&pj.Status.StartTime) {
			cancelIndex = prev
			dupes[n] = i
		}
		toCancel := pjs[cancelIndex]
		
		
		if c.config().AllowCancellations {
			build, buildExists := jbs[toCancel.ObjectMeta.Name]
			
			if buildExists && build.IsEnqueued() {
				continue
			}
			
			if buildExists {
				if err := c.jc.Abort(getJobName(&toCancel.Spec), &build); err != nil {
					c.log.WithError(err).WithFields(pjutil.ProwJobFields(&toCancel)).Warn("Cannot cancel Jenkins build")
				}
			}
		}
		toCancel.SetComplete()
		prevState := toCancel.Status.State
		toCancel.Status.State = prowapi.AbortedState
		c.log.WithFields(pjutil.ProwJobFields(&toCancel)).
			WithField("from", prevState).
			WithField("to", toCancel.Status.State).Info("Transitioning states.")
		npj, err := c.prowJobClient.Update(&toCancel)
		if err != nil {
			return err
		}
		pjs[cancelIndex] = *npj
	}
	return nil
}
func ( c * Controller ) terminateDupes ( pjs [ ] prowapi . ProwJob , jbs map [ string ] Build ) error { // "job org/repo#number" -> newest job dupes := make ( map [ string ] int ) for i , pj := range pjs { if pj . Complete ( ) || pj . Spec . Type != prowapi . PresubmitJob { continue } n := fmt . Sprintf ( " " , pj . Spec . Job , pj . Spec . Refs . Org , pj . Spec . Refs . Repo , pj . Spec . Refs . Pulls [ 0 ] . Number ) prev , ok := dupes [ n ] if ! ok { dupes [ n ] = i continue } cancelIndex := i if ( & pjs [ prev ] . Status . StartTime ) . Before ( & pj . Status . StartTime ) { cancelIndex = prev dupes [ n ] = i } toCancel := pjs [ cancelIndex ] // Allow aborting presubmit jobs for commits that have been superseded by // newer commits in GitHub pull requests. if c . config ( ) . AllowCancellations { build , buildExists := jbs [ toCancel . ObjectMeta . Name ] // Avoid cancelling enqueued builds. if buildExists && build . IsEnqueued ( ) { continue } // Otherwise, abort it. if buildExists { if err := c . jc . Abort ( getJobName ( & toCancel . Spec ) , & build ) ; err != nil { c . log . WithError ( err ) . WithFields ( pjutil . ProwJobFields ( & toCancel ) ) . Warn ( " " ) } } } toCancel . SetComplete ( ) prevState := toCancel . Status . State toCancel . Status . State = prowapi . AbortedState c . log . WithFields ( pjutil . ProwJobFields ( & toCancel ) ) . WithField ( " " , prevState ) . WithField ( " " , toCancel . Status . State ) . Info ( " " ) npj , err := c . prowJobClient . Update ( & toCancel ) if err != nil { return err } pjs [ cancelIndex ] = * npj } return nil }
// terminateDupes aborts presubmits that have a newer version. It modifies pjs
// in-place when it aborts.
terminateDupes aborts presubmits that have a newer version . It modifies pjs in - place when it aborts .