# HG changeset patch # User Sascha L. Teichmann # Date 1544787252 -3600 # Node ID 2fdd8e57542d5ea4bbe6182a397a77ceeb4cf76e # Parent e0bd82f6ee14bdc111901b41c75960cc9d25a0af Added DELETE /imports/scheduler/{id:[0-9]+} to delete a schedule from the scheduler. diff -r e0bd82f6ee14 -r 2fdd8e57542d pkg/controllers/routes.go --- a/pkg/controllers/routes.go Fri Dec 14 11:29:28 2018 +0100 +++ b/pkg/controllers/routes.go Fri Dec 14 12:34:12 2018 +0100 @@ -176,6 +176,11 @@ })).Methods(http.MethodPost) // Import scheduler configuration + api.Handle("/imports/scheduler/{id:[0-9]+}", + waterwayAdmin(&JSONHandler{ + Handle: deleteSchedule, + })).Methods(http.MethodDelete) + api.Handle("/imports/scheduler", waterwayAdmin(&JSONHandler{ Input: func() interface{} { return new(models.ImportConfig) }, diff -r e0bd82f6ee14 -r 2fdd8e57542d pkg/controllers/scheduler.go --- a/pkg/controllers/scheduler.go Fri Dec 14 11:29:28 2018 +0100 +++ b/pkg/controllers/scheduler.go Fri Dec 14 12:34:12 2018 +0100 @@ -15,11 +15,15 @@ import ( "database/sql" + "errors" + "fmt" "net/http" + "strconv" "gemma.intevation.de/gemma/pkg/auth" "gemma.intevation.de/gemma/pkg/models" "gemma.intevation.de/gemma/pkg/scheduler" + "github.com/gorilla/mux" ) const ( @@ -40,8 +44,69 @@ (username, kind, cron, send_email, auto_accept, url) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id` + + hasImportConfigurationSQL = ` +SELECT true FROM waterway.import_configuration +WHERE id = $1` + + deleteImportConfiguationSQL = ` +DELETE FROM waterway.import_configuration +WHERE id = $1` ) +func deleteSchedule( + _ interface{}, + req *http.Request, + conn *sql.Conn, +) (jr JSONResult, err error) { + + ctx := req.Context() + + id, _ := strconv.ParseInt(mux.Vars(req)["id"], 10, 64) + + var tx *sql.Tx + if tx, err = conn.BeginTx(ctx, nil); err != nil { + return + } + defer tx.Rollback() + + var found bool + err = tx.QueryRowContext(ctx, hasImportConfigurationSQL, id).Scan(&found) + switch { + case err == sql.ErrNoRows: + err = JSONError{ + Code: http.StatusNotFound, + Message: fmt.Sprintf("No schedule %d found", id), + } + return + case err != nil: + return + case !found: + err = errors.New("Unexpected result") + return + } + + if _, err = tx.ExecContext(ctx, deleteImportConfiguationSQL, id); err != nil { + return + } + + // Remove from running scheduler. + scheduler.UnbindByID(id) + + if err = tx.Commit(); err != nil { + return + } + + var result = struct { + ID int64 `json:"id"` + }{ + ID: id, + } + + jr = JSONResult{Result: &result} + return +} + func addSchedule( input interface{}, req *http.Request, @@ -97,12 +162,7 @@ } if err = tx.Commit(); err != nil { - scheduler.UnbindAction( - string(importConfig.Kind), - session.User, - &id, - ) - return + scheduler.UnbindByID(id) } var result = struct { diff -r e0bd82f6ee14 -r 2fdd8e57542d pkg/scheduler/scheduler.go --- a/pkg/scheduler/scheduler.go Fri Dec 14 11:29:28 2018 +0100 +++ b/pkg/scheduler/scheduler.go Fri Dec 14 12:34:12 2018 +0100 @@ -128,6 +128,11 @@ global.unbindAction(name, user, cfgID) } +// UnbindByID unbinds all schedules with a given id. +func UnbindByID(cfgID int64) { + global.unbindByID(cfgID) +} + // UnbindUser unbinds all schedules for a given user. func UnbindUser(user string) { global.unbindUser(user) @@ -181,6 +186,36 @@ s.cr.Start() } +func (s *scheduler) unbindByID(cfgID int64) { + s.mu.Lock() + defer s.mu.Unlock() + + entries := s.cr.Entries() + + var found bool + for _, entry := range entries { + ua := entry.Job.(*userAction) + if ua.cfgID != nil && *ua.cfgID == cfgID { + found = true + break + } + } + + if !found { + return + } + + s.cr.Stop() + s.cr = cron.New() + for _, entry := range entries { + ua := entry.Job.(*userAction) + if ua.cfgID == nil || *ua.cfgID != cfgID { + s.cr.Schedule(entry.Schedule, entry.Job) + } + } + s.cr.Start() +} + func (s *scheduler) unbindAction(name, user string, cfgID *int64) { s.mu.Lock() defer s.mu.Unlock()