| OLD | NEW |
| 1 /* | 1 /* |
| 2 Handlers for retrieving pending tasks. | 2 Handlers for retrieving pending tasks. |
| 3 */ | 3 */ |
| 4 | 4 |
| 5 package pending_tasks | 5 package pending_tasks |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "database/sql" | 8 "database/sql" |
| 9 "encoding/json" | 9 "encoding/json" |
| 10 "fmt" | 10 "fmt" |
| 11 "io" | 11 "io" |
| 12 "net/http" | 12 "net/http" |
| 13 "path/filepath" | 13 "path/filepath" |
| 14 "text/template" | 14 "text/template" |
| 15 | 15 |
| 16 "github.com/gorilla/mux" | 16 "github.com/gorilla/mux" |
| 17 | 17 |
| 18 "go.skia.org/infra/ct/go/ctfe/admin_tasks" | 18 "go.skia.org/infra/ct/go/ctfe/admin_tasks" |
| 19 "go.skia.org/infra/ct/go/ctfe/capture_skps" | 19 "go.skia.org/infra/ct/go/ctfe/capture_skps" |
| 20 "go.skia.org/infra/ct/go/ctfe/chromium_builds" | 20 "go.skia.org/infra/ct/go/ctfe/chromium_builds" |
| 21 "go.skia.org/infra/ct/go/ctfe/chromium_perf" | 21 "go.skia.org/infra/ct/go/ctfe/chromium_perf" |
| 22 "go.skia.org/infra/ct/go/ctfe/lua_scripts" | 22 "go.skia.org/infra/ct/go/ctfe/lua_scripts" |
| 23 "go.skia.org/infra/ct/go/ctfe/task_common" | 23 "go.skia.org/infra/ct/go/ctfe/task_common" |
| 24 "go.skia.org/infra/ct/go/ctfe/task_types" |
| 24 ctfeutil "go.skia.org/infra/ct/go/ctfe/util" | 25 ctfeutil "go.skia.org/infra/ct/go/ctfe/util" |
| 25 "go.skia.org/infra/ct/go/db" | 26 "go.skia.org/infra/ct/go/db" |
| 26 skutil "go.skia.org/infra/go/util" | 27 skutil "go.skia.org/infra/go/util" |
| 27 ) | 28 ) |
| 28 | 29 |
| 29 var ( | 30 var ( |
| 30 taskTables = []string{ | |
| 31 db.TABLE_CHROMIUM_PERF_TASKS, | |
| 32 db.TABLE_CAPTURE_SKPS_TASKS, | |
| 33 db.TABLE_LUA_SCRIPT_TASKS, | |
| 34 db.TABLE_CHROMIUM_BUILD_TASKS, | |
| 35 db.TABLE_RECREATE_PAGE_SETS_TASKS, | |
| 36 db.TABLE_RECREATE_WEBPAGE_ARCHIVES_TASKS, | |
| 37 } | |
| 38 | |
| 39 runsHistoryTemplate *template.Template = nil | 31 runsHistoryTemplate *template.Template = nil |
| 40 pendingTasksTemplate *template.Template = nil | 32 pendingTasksTemplate *template.Template = nil |
| 41 ) | 33 ) |
| 42 | 34 |
| 43 func ReloadTemplates(resourcesDir string) { | 35 func ReloadTemplates(resourcesDir string) { |
| 44 runsHistoryTemplate = template.Must(template.ParseFiles( | 36 runsHistoryTemplate = template.Must(template.ParseFiles( |
| 45 filepath.Join(resourcesDir, "templates/runs_history.html"), | 37 filepath.Join(resourcesDir, "templates/runs_history.html"), |
| 46 filepath.Join(resourcesDir, "templates/header.html"), | 38 filepath.Join(resourcesDir, "templates/header.html"), |
| 47 filepath.Join(resourcesDir, "templates/titlebar.html"), | 39 filepath.Join(resourcesDir, "templates/titlebar.html"), |
| 48 )) | 40 )) |
| 49 | 41 |
| 50 pendingTasksTemplate = template.Must(template.ParseFiles( | 42 pendingTasksTemplate = template.Must(template.ParseFiles( |
| 51 filepath.Join(resourcesDir, "templates/pending_tasks.html"), | 43 filepath.Join(resourcesDir, "templates/pending_tasks.html"), |
| 52 filepath.Join(resourcesDir, "templates/header.html"), | 44 filepath.Join(resourcesDir, "templates/header.html"), |
| 53 filepath.Join(resourcesDir, "templates/titlebar.html"), | 45 filepath.Join(resourcesDir, "templates/titlebar.html"), |
| 54 )) | 46 )) |
| 55 } | 47 } |
| 56 | 48 |
| 57 func runsHistoryView(w http.ResponseWriter, r *http.Request) { | 49 func runsHistoryView(w http.ResponseWriter, r *http.Request) { |
| 58 ctfeutil.ExecuteSimpleTemplate(runsHistoryTemplate, w, r) | 50 ctfeutil.ExecuteSimpleTemplate(runsHistoryTemplate, w, r) |
| 59 } | 51 } |
| 60 | 52 |
| 61 func getAllPendingTasks() ([]task_common.Task, error) { | 53 // GetOldestPendingTask returns the oldest pending task of any type. |
| 62 » tasks := []task_common.Task{} | 54 func GetOldestPendingTask() (task_common.Task, error) { |
| 63 » for _, tableName := range taskTables { | 55 » var oldestTask task_common.Task |
| 64 » » var task task_common.Task | 56 » for _, task := range task_types.Prototypes() { |
| 65 » » query := fmt.Sprintf("SELECT * FROM %s WHERE ts_completed IS NUL
L ORDER BY ts_added LIMIT 1;", tableName) | 57 » » query := fmt.Sprintf( |
| 66 » » switch tableName { | 58 » » » "SELECT * FROM %s WHERE ts_completed IS NULL ORDER BY ts
_added LIMIT 1;", |
| 67 » » case db.TABLE_CHROMIUM_PERF_TASKS: | 59 » » » task.TableName()) |
| 68 » » » task = &chromium_perf.DBTask{} | |
| 69 » » case db.TABLE_CAPTURE_SKPS_TASKS: | |
| 70 » » » task = &capture_skps.DBTask{} | |
| 71 » » case db.TABLE_LUA_SCRIPT_TASKS: | |
| 72 » » » task = &lua_scripts.DBTask{} | |
| 73 » » case db.TABLE_CHROMIUM_BUILD_TASKS: | |
| 74 » » » task = &chromium_builds.DBTask{} | |
| 75 » » case db.TABLE_RECREATE_PAGE_SETS_TASKS: | |
| 76 » » » task = &admin_tasks.RecreatePageSetsDBTask{} | |
| 77 » » case db.TABLE_RECREATE_WEBPAGE_ARCHIVES_TASKS: | |
| 78 » » » task = &admin_tasks.RecreateWebpageArchivesDBTask{} | |
| 79 » » default: | |
| 80 » » » panic("Unknown table " + tableName) | |
| 81 » » } | |
| 82 | |
| 83 if err := db.DB.Get(task, query); err == sql.ErrNoRows { | 60 if err := db.DB.Get(task, query); err == sql.ErrNoRows { |
| 84 continue | 61 continue |
| 85 } else if err != nil { | 62 } else if err != nil { |
| 86 return nil, fmt.Errorf("Failed to query DB: %v", err) | 63 return nil, fmt.Errorf("Failed to query DB: %v", err) |
| 87 } | 64 } |
| 88 » » tasks = append(tasks, task) | 65 » » if oldestTask == nil { |
| 66 » » » oldestTask = task |
| 67 » » } else if oldestTask.GetCommonCols().TsAdded.Int64 > |
| 68 » » » task.GetCommonCols().TsAdded.Int64 { |
| 69 » » » oldestTask = task |
| 70 » » } |
| 89 } | 71 } |
| 90 » return tasks, nil | 72 » return oldestTask, nil |
| 91 } | 73 } |
| 92 | 74 |
| 93 // Union of all task types, to be easily marshalled/unmarshalled to/from JSON. A
t most one field | 75 // Union of all task types, to be easily marshalled/unmarshalled to/from JSON. A
t most one field |
| 94 // should be non-nil when serialized as JSON. | 76 // should be non-nil when serialized as JSON. |
| 95 type oldestPendingTask struct { | 77 type oldestPendingTask struct { |
| 96 ChromiumPerf *chromium_perf.DBTask | 78 ChromiumPerf *chromium_perf.DBTask |
| 97 CaptureSkps *capture_skps.DBTask | 79 CaptureSkps *capture_skps.DBTask |
| 98 LuaScript *lua_scripts.DBTask | 80 LuaScript *lua_scripts.DBTask |
| 99 ChromiumBuild *chromium_builds.DBTask | 81 ChromiumBuild *chromium_builds.DBTask |
| 100 RecreatePageSets *admin_tasks.RecreatePageSetsDBTask | 82 RecreatePageSets *admin_tasks.RecreatePageSetsDBTask |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 case pending.RecreateWebpageArchives != nil: | 131 case pending.RecreateWebpageArchives != nil: |
| 150 return pending.RecreateWebpageArchives, nil | 132 return pending.RecreateWebpageArchives, nil |
| 151 default: | 133 default: |
| 152 return nil, nil | 134 return nil, nil |
| 153 } | 135 } |
| 154 } | 136 } |
| 155 | 137 |
| 156 func getOldestPendingTaskHandler(w http.ResponseWriter, r *http.Request) { | 138 func getOldestPendingTaskHandler(w http.ResponseWriter, r *http.Request) { |
| 157 w.Header().Set("Content-Type", "application/json") | 139 w.Header().Set("Content-Type", "application/json") |
| 158 | 140 |
| 159 » tasks, err := getAllPendingTasks() | 141 » oldestTask, err := GetOldestPendingTask() |
| 160 if err != nil { | 142 if err != nil { |
| 161 » » skutil.ReportError(w, r, err, fmt.Sprintf("Failed to get all pen
ding tasks: %v", err)) | 143 » » skutil.ReportError(w, r, err, "Failed to get oldest pending task
") |
| 162 return | 144 return |
| 163 } | 145 } |
| 164 | 146 |
| 165 var oldestTask task_common.Task | |
| 166 for _, task := range tasks { | |
| 167 if oldestTask == nil { | |
| 168 oldestTask = task | |
| 169 } else if oldestTask.GetCommonCols().TsAdded.Int64 > | |
| 170 task.GetCommonCols().TsAdded.Int64 { | |
| 171 oldestTask = task | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 if err := EncodeTask(w, oldestTask); err != nil { | 147 if err := EncodeTask(w, oldestTask); err != nil { |
| 176 skutil.ReportError(w, r, err, | 148 skutil.ReportError(w, r, err, |
| 177 fmt.Sprintf("Failed to encode JSON for %#v", oldestTask)
) | 149 fmt.Sprintf("Failed to encode JSON for %#v", oldestTask)
) |
| 178 return | 150 return |
| 179 } | 151 } |
| 180 } | 152 } |
| 181 | 153 |
| 154 // GetPendingTaskCount returns the total number of pending tasks of all types. O
n error, the first |
| 155 // return value will be -1 and the second return value will be non-nil. |
| 156 func GetPendingTaskCount() (int64, error) { |
| 157 var result int64 = 0 |
| 158 params := task_common.QueryParams{ |
| 159 PendingOnly: true, |
| 160 CountQuery: true, |
| 161 } |
| 162 for _, prototype := range task_types.Prototypes() { |
| 163 query, args := task_common.DBTaskQuery(prototype, params) |
| 164 var countVal int64 = 0 |
| 165 if err := db.DB.Get(&countVal, query, args...); err != nil { |
| 166 return -1, err |
| 167 } |
| 168 result += countVal |
| 169 } |
| 170 return result, nil |
| 171 } |
| 172 |
| 182 func pendingTasksView(w http.ResponseWriter, r *http.Request) { | 173 func pendingTasksView(w http.ResponseWriter, r *http.Request) { |
| 183 ctfeutil.ExecuteSimpleTemplate(pendingTasksTemplate, w, r) | 174 ctfeutil.ExecuteSimpleTemplate(pendingTasksTemplate, w, r) |
| 184 } | 175 } |
| 185 | 176 |
| 186 func AddHandlers(r *mux.Router) { | 177 func AddHandlers(r *mux.Router) { |
| 187 // Runs history handlers. | 178 // Runs history handlers. |
| 188 r.HandleFunc("/"+ctfeutil.RUNS_HISTORY_URI, runsHistoryView).Methods("GE
T") | 179 r.HandleFunc("/"+ctfeutil.RUNS_HISTORY_URI, runsHistoryView).Methods("GE
T") |
| 189 | 180 |
| 190 // Task Queue handlers. | 181 // Task Queue handlers. |
| 191 r.HandleFunc("/"+ctfeutil.PENDING_TASKS_URI, pendingTasksView).Methods("
GET") | 182 r.HandleFunc("/"+ctfeutil.PENDING_TASKS_URI, pendingTasksView).Methods("
GET") |
| 192 r.HandleFunc("/"+ctfeutil.GET_OLDEST_PENDING_TASK_URI, getOldestPendingT
askHandler).Methods("GET") | 183 r.HandleFunc("/"+ctfeutil.GET_OLDEST_PENDING_TASK_URI, getOldestPendingT
askHandler).Methods("GET") |
| 193 } | 184 } |
| OLD | NEW |