Beispiel #1
0
func (a *Agent) HandleEventJobOffered(event registry.Event) {
	jo := event.Payload.(job.JobOffer)
	log.V(1).Infof("EventJobOffered(%s): verifying ability to run Job", jo.Job.Name)

	a.state.Lock()
	defer a.state.Unlock()

	// Everything we check against could change over time, so we track all
	// offers starting here for future bidding even if we can't bid now
	a.state.TrackOffer(jo)
	a.state.TrackJobPeers(jo.Job.Name, jo.Job.Payload.Peers)

	metadata := extractMachineMetadata(jo.Job.Payload.Requirements)
	if !a.Machine.HasMetadata(metadata) {
		log.V(1).Infof("EventJobOffered(%s): local Machine Metadata insufficient", jo.Job.Name)
		return
	}

	if a.hasConflict(&jo.Job) {
		log.V(1).Infof("EventJobOffered(%s): local Job conflict, ignoring offer", jo.Job.Name)
		return
	}

	if !a.hasAllLocalPeers(&jo.Job) {
		log.V(1).Infof("EventJobOffered(%s): necessary peer Jobs are not running locally", jo.Job.Name)
		return
	}

	log.Infof("EventJobOffered(%s): passed all criteria, submitting JobBid", jo.Job.Name)
	jb := job.NewBid(jo.Job.Name, a.Machine.BootId)
	a.Registry.SubmitJobBid(jb)
	a.state.TrackBid(jo.Job.Name)
}
Beispiel #2
0
// Only call this from a locked AgentState context
func (a *Agent) bidForPossibleOffers() {
	for _, offer := range a.state.GetUnbadeOffers() {
		if !a.hasConflict(&offer.Job) && a.hasAllLocalPeers(&offer.Job) {
			log.Infof("Unscheduled Job(%s) has no local conflicts, submitting JobBid", offer.Job.Name)
			jb := job.NewBid(offer.Job.Name, a.Machine.BootId)
			a.Registry.SubmitJobBid(jb)

			a.state.TrackBid(jb.JobName)
		}
	}
}
Beispiel #3
0
func (a *Agent) HandleEventJobScheduled(event registry.Event) {
	jobName := event.Payload.(string)

	a.state.Lock()
	defer a.state.Unlock()

	a.state.DropOffer(jobName)
	a.state.DropBid(jobName)

	if event.Context.BootId != a.Machine.BootId {
		log.V(1).Infof("EventJobScheduled(%s): Job not scheduled to this Agent", jobName)
		a.bidForPossibleOffers()
		return
	} else {
		log.V(1).Infof("EventJobScheduled(%s): Job scheduled to this Agent", jobName)
	}

	log.V(1).Infof("EventJobScheduled(%s): Fetching Job from Registry", jobName)
	j := a.Registry.GetJob(jobName)

	if j == nil {
		log.V(1).Infof("EventJobScheduled(%s): Job not found in Registry")
		return
	}

	// Reassert there are no conflicts
	if a.hasConflict(j) {
		log.V(1).Infof("EventJobScheduled(%s): Local conflict found, cancelling Job", jobName)
		a.Registry.CancelJob(jobName)
		return
	}

	log.Infof("EventJobScheduled(%s): Starting Job", j.Name)
	a.Manager.StartJob(j)

	reversePeers := a.state.GetJobsByPeer(jobName)
	for _, peer := range reversePeers {
		log.V(1).Infof("EventJobScheduled(%s): Found unresolved offer for Peer(%s)", jobName, peer)

		if peerJob := a.Registry.GetJob(peer); !a.hasConflict(peerJob) {
			log.Infof("EventJobScheduled(%s): Submitting JobBid for Peer(%s)", jobName, peer)
			jb := job.NewBid(peer, a.Machine.BootId)
			a.Registry.SubmitJobBid(jb)

			a.state.TrackBid(jb.JobName)
		} else {
			log.V(1).Infof("EventJobScheduled(%s): Would submit JobBid for Peer(%s), but local conflict exists", jobName, peer)
		}
	}
}
Beispiel #4
0
func filterEventJobBidSubmitted(resp *etcd.Response) *Event {
	if resp.Action != "set" {
		return nil
	}

	dir, machName := path.Split(resp.Node.Key)
	dir, prefix := path.Split(strings.TrimSuffix(dir, "/"))

	if prefix != "bids" {
		return nil
	}

	dir, jobName := path.Split(strings.TrimSuffix(dir, "/"))
	prefix = path.Base(strings.TrimSuffix(dir, "/"))

	if prefix != offerPrefix {
		return nil
	}

	jb := job.NewBid(jobName, machName)
	return &Event{"EventJobBidSubmitted", *jb, nil}
}