Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: build_scheduler/go/db/db.go

Issue 2296763008: [task scheduler] Move files from build_scheduler/ to task_scheduler/ (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build_scheduler/go/db/comments_test.go ('k') | build_scheduler/go/db/local_db/busywork/main.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 package db
2
3 import (
4 "errors"
5 "io"
6 "time"
7
8 "github.com/skia-dev/glog"
9 )
10
11 const (
12 // Maximum number of simultaneous GetModifiedTasks users.
13 MAX_MODIFIED_TASKS_USERS = 10
14
15 // Expiration for GetModifiedTasks users.
16 MODIFIED_TASKS_TIMEOUT = 10 * time.Minute
17
18 // Retries attempted by UpdateWithRetries and UpdateTaskWithRetries.
19 NUM_RETRIES = 5
20 )
21
22 var (
23 ErrAlreadyExists = errors.New("Object already exists and modification not allowed.")
24 ErrConcurrentUpdate = errors.New("Concurrent update")
25 ErrNotFound = errors.New("Task with given ID does not exist")
26 ErrTooManyUsers = errors.New("Too many users")
27 ErrUnknownId = errors.New("Unknown ID")
28 )
29
30 func IsAlreadyExists(e error) bool {
31 return e != nil && e.Error() == ErrAlreadyExists.Error()
32 }
33
34 func IsConcurrentUpdate(e error) bool {
35 return e != nil && e.Error() == ErrConcurrentUpdate.Error()
36 }
37
38 func IsNotFound(e error) bool {
39 return e != nil && e.Error() == ErrNotFound.Error()
40 }
41
42 func IsTooManyUsers(e error) bool {
43 return e != nil && e.Error() == ErrTooManyUsers.Error()
44 }
45
46 func IsUnknownId(e error) bool {
47 return e != nil && e.Error() == ErrUnknownId.Error()
48 }
49
50 // TaskReader is a read-only view of a DB.
51 type TaskReader interface {
52 io.Closer
53
54 // GetModifiedTasks returns all tasks modified since the last time
55 // GetModifiedTasks was run with the given id.
56 GetModifiedTasks(string) ([]*Task, error)
57
58 // GetTaskById returns the task with the given Id field. Returns nil, ni l if
59 // task is not found.
60 GetTaskById(string) (*Task, error)
61
62 // GetTasksFromDateRange retrieves all tasks which started in the given date range.
63 GetTasksFromDateRange(time.Time, time.Time) ([]*Task, error)
64
65 // StartTrackingModifiedTasks initiates tracking of modified tasks for
66 // the current caller. Returns a unique ID which can be used by the call er
67 // to retrieve tasks which have been modified since the last query. The ID
68 // expires after a period of inactivity.
69 StartTrackingModifiedTasks() (string, error)
70
71 // StopTrackingModifiedTasks cancels tracking of modified tasks for the
72 // provided ID.
73 StopTrackingModifiedTasks(string)
74 }
75
76 // DB is used by the task scheduler to store Tasks.
77 type DB interface {
78 TaskReader
79
80 // AssignId sets the given task's Id field. Does not insert the task int o the
81 // database.
82 AssignId(*Task) error
83
84 // PutTask inserts or updates the Task in the database. Task's Id field must
85 // be empty or set with AssignId. PutTask will set Task.DbModified.
86 PutTask(*Task) error
87
88 // PutTasks inserts or updates the Tasks in the database. Each Task's Id field
89 // must be empty or set with AssignId. Each Task's DbModified field will be
90 // set.
91 PutTasks([]*Task) error
92 }
93
94 // UpdateWithRetries wraps a call to db.PutTasks with retries. It calls
95 // db.PutTasks(f()) repeatedly until one of the following happen:
96 // - f or db.PutTasks returns an error, which is then returned from
97 // UpdateWithRetries;
98 // - PutTasks succeeds, in which case UpdateWithRetries returns the updated
99 // Tasks returned by f;
100 // - retries are exhausted, in which case UpdateWithRetries returns
101 // ErrConcurrentUpdate.
102 //
103 // Within f, tasks should be refreshed from the DB, e.g. with
104 // db.GetModifiedTasks or db.GetTaskById.
105 func UpdateWithRetries(db DB, f func() ([]*Task, error)) ([]*Task, error) {
106 var lastErr error
107 for i := 0; i < NUM_RETRIES; i++ {
108 t, err := f()
109 if err != nil {
110 return nil, err
111 }
112 lastErr = db.PutTasks(t)
113 if lastErr == nil {
114 return t, nil
115 } else if !IsConcurrentUpdate(lastErr) {
116 return nil, lastErr
117 }
118 }
119 glog.Warningf("UpdateWithRetries: %d consecutive ErrConcurrentUpdate.", NUM_RETRIES)
120 return nil, lastErr
121 }
122
123 // UpdateTaskWithRetries reads, updates, and writes a single Task in the DB. It:
124 // 1. reads the task with the given id,
125 // 2. calls f on that task, and
126 // 3. calls db.PutTask() on the updated task
127 // 4. repeats from step 1 as long as PutTasks returns ErrConcurrentUpdate and
128 // retries have not been exhausted.
129 // Returns the updated task if it was successfully updated in the DB.
130 // Immediately returns ErrNotFound if db.GetTaskById(id) returns nil.
131 // Immediately returns any error returned from f or from PutTasks (except
132 // ErrConcurrentUpdate). Returns ErrConcurrentUpdate if retries are exhausted.
133 func UpdateTaskWithRetries(db DB, id string, f func(*Task) error) (*Task, error) {
134 tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
135 t, err := db.GetTaskById(id)
136 if err != nil {
137 return nil, err
138 }
139 if t == nil {
140 return nil, ErrNotFound
141 }
142 err = f(t)
143 if err != nil {
144 return nil, err
145 }
146 return []*Task{t}, nil
147 })
148 if err != nil {
149 return nil, err
150 } else {
151 return tasks[0], nil
152 }
153 }
154
155 // RemoteDB allows retrieving tasks and full access to comments.
156 type RemoteDB interface {
157 TaskReader
158 CommentDB
159 }
OLDNEW
« no previous file with comments | « build_scheduler/go/db/comments_test.go ('k') | build_scheduler/go/db/local_db/busywork/main.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698