Exemple #1
0
func (h *jobAPI) AddJob(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// TODO(titanous): validate UUID
	id := ps.ByName("id")

	log := h.host.log.New("fn", "AddJob", "job.id", id)

	if shutdown.IsActive() {
		log.Warn("refusing to start job due to active shutdown")
		httphelper.JSON(w, 500, struct{}{})
		return
	}

	log.Info("decoding job")
	job := &host.Job{ID: id}
	if err := httphelper.DecodeJSON(r, job); err != nil {
		log.Error("error decoding job", "err", err)
		httphelper.Error(w, err)
		return
	}

	log.Info("acquiring state database")
	if err := h.host.state.Acquire(); err != nil {
		log.Error("error acquiring state database", "err", err)
		httphelper.Error(w, err)
		return
	}

	h.host.state.AddJob(job)

	go func() {
		// TODO(titanous): ratelimit this goroutine?
		log.Info("running job")
		err := h.host.backend.Run(job, nil)
		h.host.state.Release()
		if err != nil {
			log.Error("error running job", "err", err)
			h.host.state.SetStatusFailed(job.ID, err)
		}
	}()

	// TODO(titanous): return 201 Accepted
	httphelper.JSON(w, 200, struct{}{})
}
Exemple #2
0
func (h *jobAPI) AddJob(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	if shutdown.IsActive() {
		httphelper.JSON(w, 500, struct{}{})
		return
	}

	job := &host.Job{}
	if err := httphelper.DecodeJSON(r, job); err != nil {
		httphelper.Error(w, err)
		return
	}
	// TODO(titanous): validate UUID
	job.ID = ps.ByName("id")

	go func() {
		// TODO(titanous): ratelimit this goroutine?
		if err := h.host.backend.Run(job, nil); err != nil {
			h.host.state.SetStatusFailed(job.ID, err)
		}
	}()

	// TODO(titanous): return 201 Accepted
	httphelper.JSON(w, 200, struct{}{})
}
Exemple #3
0
func (h *jobAPI) AddJob(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	// TODO(titanous): validate UUID
	id := ps.ByName("id")

	log := h.host.log.New("fn", "AddJob", "job.id", id)

	if !h.addJobRateLimitBucket.Take() {
		log.Warn("maximum concurrent AddJob calls running")
		httphelper.Error(w, httphelper.JSONError{
			Code:    httphelper.RatelimitedErrorCode,
			Message: "maximum concurrent AddJob calls running, try again later",
			Retry:   true,
		})
		return
	}

	if shutdown.IsActive() {
		log.Warn("refusing to start job due to active shutdown")
		httphelper.JSON(w, 500, struct{}{})
		h.addJobRateLimitBucket.Put()
		return
	}

	log.Info("decoding job")
	job := &host.Job{ID: id}
	if err := httphelper.DecodeJSON(r, job); err != nil {
		log.Error("error decoding job", "err", err)
		httphelper.Error(w, err)
		h.addJobRateLimitBucket.Put()
		return
	}
	if len(job.Mountspecs) == 0 {
		log.Warn("rejecting job as no mountspecs set")
		httphelper.ValidationError(w, "mountspecs", "must be set")
		h.addJobRateLimitBucket.Put()
		return
	}

	log.Info("acquiring state database")
	if err := h.host.state.Acquire(); err != nil {
		log.Error("error acquiring state database", "err", err)
		httphelper.Error(w, err)
		h.addJobRateLimitBucket.Put()
		return
	}

	if err := h.host.state.AddJob(job); err != nil {
		log.Error("error adding job to state database", "err", err)
		if err == ErrJobExists {
			httphelper.ConflictError(w, err.Error())
		} else {
			httphelper.Error(w, err)
		}
		h.addJobRateLimitBucket.Put()
		return
	}

	go func() {
		log.Info("running job")
		err := h.host.backend.Run(job, nil, h.addJobRateLimitBucket)
		h.host.state.Release()
		if err != nil {
			log.Error("error running job", "err", err)
			h.host.state.SetStatusFailed(job.ID, err)
		}
		h.addJobRateLimitBucket.Put()
	}()

	// TODO(titanous): return 201 Accepted
	httphelper.JSON(w, 200, struct{}{})
}