Exemple #1
0
// this function ensures that the job has the right worker before queuing it
func prepareJobForQueue(j Job) {

	jobClaims.claimJob(j.JobHeader)
	ja := messages.JobAck{j.JobHeader}
	if line, ok := getLine(j.Conn); ok {
		line.Out <- ja.Message()
	}

	pr := GetProject(j.Project)

	// first, ensure that we've got the worker
	alreadyRequested := false
waitforworker:
	for {
		w, ok := pr.GetWorker(j.Name)
		if ok && j.Version <= w.Version {
			// we've already got the right worker
			break
		}
		workerChan := make(chan Worker)
		workerSub := func(msg messages.Message, line messages.Line) (keepgoing bool) {
			if string(msg.Payload["type"]) != messages.WorkerType {
				return true
			}

			worker, err := messages.WorkerFromMessage(msg)
			if err != nil {
				return true
			}

			if worker.Project != j.Project || worker.Name != j.Name {
				return true
			}

			if worker.Version < j.Version {
				return true
			}

			// this is our worker
			w := Worker{worker, line.Conn}
			pr.AddWorker(w)
			workerChan <- w
			// stop this subscription
			return false
		}

		if !alreadyRequested {
			alreadyRequested = true
			log.Printf("requesting worker for %v", j)
			wr := messages.WorkerRequest{
				Project: j.Project,
				Name:    j.Name,
				Version: j.Version,
			}
			line, ok := getLine(j.Conn)
			if !ok {
				log.Printf("job came from lost source")
			}
			line.Out <- wr.Message()
		}

		go subscribe(workerSub)
		timeout := time.NewTimer(2e9)
		select {
		case w = <-workerChan:
			break waitforworker
		case <-timeout.C:
			/*
				this timeout is here because we might have received the worker between the first
				check and when the subscription went active
			*/
		}
		timeout.Stop()
	}
	log.Printf("enqueuing %v", j)

	jobQueue.Push <- j
}
Exemple #2
0
func handleMessages(mline messages.Line) {
	log.Println("connected to", mline.Conn.RemoteAddr())
	defer log.Println("lost connection to", mline.Conn.RemoteAddr())

	for msg := range mline.In {
		go func(msg messages.Message, conn *net.TCPConn) {
			if msg.Broadcast {
				broadcastMessage(msg)
			}

			// toss this to subscribers
			go func(msg messages.Message, line messages.Line) {
				subscriberLock.Lock()
				for _, ch := range subscriberChans {
					ch <- MsgSrc{msg, line}
				}
				subscriberLock.Unlock()
			}(msg, mline)

			typ, ok := msg.Payload["type"]

			if !ok {
				log.Println("received message with no type")
				return
			}
			switch string(typ) {
			case "load":
				l, err := LoadFromMessage(msg, conn)
				if err != nil {
					log.Println(err)
					return
				}
				recvLoad(l)
			case "ident":
				i, err := IdentFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvIdent(i, conn)
			case messages.WorkerType:
				w, err := messages.WorkerFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvWorker(Worker{w, conn})
			case messages.WorkerRequestType:
				w, err := messages.WorkerRequestFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvWorkerRequest(WorkerRequest{w, conn})
			case messages.JobType:
				j, err := messages.JobFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvJob(Job{j, conn})
			case messages.JobAckType:
				ja, err := messages.JobAckFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvJobAck(ja)
			case messages.JobStatusRequestType:
				jsr, err := messages.JobStatusRequestFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvJobStatusRequest(jsr)
			case messages.JobStatusType:
				js, err := messages.JobStatusFromMessage(msg)
				if err != nil {
					log.Println(err)
					return
				}
				recvJobStatus(js)
			}
		}(msg, mline.Conn)
	}
}