prow/crier/controller.go
func (c *Controller) processNextItem() bool {
	key, quit := c.queue.Get()
	if quit {
		return false
	}

	defer c.queue.Done(key)

	// assert the string out of the key (format `namespace/name`)
	keyRaw := key.(string)
	namespace, name, err := cache.SplitMetaNamespaceKey(keyRaw)
	if err != nil {
		logrus.WithError(err).WithField("prowjob", keyRaw).Error("invalid resource key")
		c.queue.Forget(key)
		return true
	}

	// take the string key and get the object out of the indexer
	//
	// item will contain the complex object for the resource and
	// exists is a bool that'll indicate whether or not the
	// resource was created (true) or deleted (false)
	//
	// if there is an error in getting the key from the index
	// then we want to retry this particular queue key a certain
	// number of times (5 here) before we forget the queue key
	// and throw an error
	pj, err := c.informer.Lister().ProwJobs(namespace).Get(name)
	if err != nil {
		if errors.IsNotFound(err) {
			logrus.WithField("prowjob", keyRaw).Info("object no longer exist")
			c.queue.Forget(key)
			return true
		}

		return c.retry(key, err)
	}

	// not belong to the current reporter
	if !c.reporter.ShouldReport(pj) {
		c.queue.Forget(key)
		return true
	}

	// we set omitempty on PrevReportStates, so here we need to init it if is nil
	if pj.Status.PrevReportStates == nil {
		pj.Status.PrevReportStates = map[string]v1.ProwJobState{}
	}

	// already reported current state
	if pj.Status.PrevReportStates[c.reporter.GetName()] == pj.Status.State {
		logrus.WithField("prowjob", keyRaw).Info("Already reported")
		c.queue.Forget(key)
		return true
	}

	logrus.WithField("prowjob", keyRaw).Infof("Will report state : %s", pj.Status.State)
	pjs, err := c.reporter.Report(pj)
	if err != nil {
		fields := logrus.Fields{
			"prowjob":   keyRaw,
			"jobName":   pj.Name,
			"jobStatus": pj.Status,
		}
		logrus.WithError(err).WithFields(fields).Error("failed to report job")
		return c.retry(key, err)
	}

	logrus.WithField("prowjob", keyRaw).Info("Updated job, now will update pj")
	for _, pjob := range pjs {
		if err := c.updateReportState(pjob); err != nil {
			logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to update report state")

			// theoretically patch should not have this issue, but in case:
			// it might be out-dated, try to re-fetch pj and try again

			updatedPJ, err := c.pjclientset.Prow().ProwJobs(pjob.Namespace).Get(pjob.Name, metav1.GetOptions{})
			if err != nil {
				logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to get prowjob from apiserver")
				c.queue.Forget(key)
				return true
			}

			if err := c.updateReportState(updatedPJ); err != nil {
				// shrug
				logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to update report state again, give up")
				c.queue.Forget(key)
				return true
			}
		}

		logrus.WithField("prowjob", keyRaw).Infof("Hunky Dory!, pj : %v, state : %s", pjob.Spec.Job, pjob.Status.State)
	}
	c.queue.Forget(key)
	return true
}
func (c *Controller) processNextItem() bool {
	key, quit := c.queue.Get()
	if quit {
		return false
	}

	defer c.queue.Done(key)

	// assert the string out of the key (format `namespace/name`)
	keyRaw := key.(string)
	namespace, name, err := cache.SplitMetaNamespaceKey(keyRaw)
	if err != nil {
		logrus.WithError(err).WithField("prowjob", keyRaw).Error("invalid resource key")
		c.queue.Forget(key)
		return true
	}

	// take the string key and get the object out of the indexer
	//
	// item will contain the complex object for the resource and
	// exists is a bool that'll indicate whether or not the
	// resource was created (true) or deleted (false)
	//
	// if there is an error in getting the key from the index
	// then we want to retry this particular queue key a certain
	// number of times (5 here) before we forget the queue key
	// and throw an error
	pj, err := c.informer.Lister().ProwJobs(namespace).Get(name)
	if err != nil {
		if errors.IsNotFound(err) {
			logrus.WithField("prowjob", keyRaw).Info("object no longer exist")
			c.queue.Forget(key)
			return true
		}

		return c.retry(key, err)
	}

	// not belong to the current reporter
	if !c.reporter.ShouldReport(pj) {
		c.queue.Forget(key)
		return true
	}

	// we set omitempty on PrevReportStates, so here we need to init it if is nil
	if pj.Status.PrevReportStates == nil {
		pj.Status.PrevReportStates = map[string]v1.ProwJobState{}
	}

	// already reported current state
	if pj.Status.PrevReportStates[c.reporter.GetName()] == pj.Status.State {
		logrus.WithField("prowjob", keyRaw).Info("Already reported")
		c.queue.Forget(key)
		return true
	}

	logrus.WithField("prowjob", keyRaw).Infof("Will report state : %s", pj.Status.State)
	pjs, err := c.reporter.Report(pj)
	if err != nil {
		fields := logrus.Fields{
			"prowjob":   keyRaw,
			"jobName":   pj.Name,
			"jobStatus": pj.Status,
		}
		logrus.WithError(err).WithFields(fields).Error("failed to report job")
		return c.retry(key, err)
	}

	logrus.WithField("prowjob", keyRaw).Info("Updated job, now will update pj")
	for _, pjob := range pjs {
		if err := c.updateReportState(pjob); err != nil {
			logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to update report state")

			// theoretically patch should not have this issue, but in case:
			// it might be out-dated, try to re-fetch pj and try again

			updatedPJ, err := c.pjclientset.Prow().ProwJobs(pjob.Namespace).Get(pjob.Name, metav1.GetOptions{})
			if err != nil {
				logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to get prowjob from apiserver")
				c.queue.Forget(key)
				return true
			}

			if err := c.updateReportState(updatedPJ); err != nil {
				// shrug
				logrus.WithError(err).WithField("prowjob", keyRaw).Error("failed to update report state again, give up")
				c.queue.Forget(key)
				return true
			}
		}

		logrus.WithField("prowjob", keyRaw).Infof("Hunky Dory!, pj : %v, state : %s", pjob.Spec.Job, pjob.Status.State)
	}
	c.queue.Forget(key)
	return true
}
// processNextItem retrieves each queued item and takes the necessary handler action based off of if
// the item was created or deleted.