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{}{}) }
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{}{}) }
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{}{}) }