-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(database): add support for schedules #834
Conversation
Codecov Report
@@ Coverage Diff @@
## main #834 +/- ##
=======================================
Coverage ? 59.48%
=======================================
Files ? 284
Lines ? 15798
Branches ? 0
=======================================
Hits ? 9397
Misses ? 5958
Partials ? 443 |
…to feature/schedule/database
…to feature/schedule/database
…to feature/schedule/database
… into feature/schedule/database
@jbrockopp can we mark this as Ready for review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple random typos / nits as well as a question related to the count request for those list functions.
// count the results | ||
count, err := e.CountSchedules() | ||
if err != nil { | ||
return nil, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if this is necessary. It doesn't look like we use it other than short circuiting an empty table, and the COUNT
query is fairly taxing (at least in Postgres): https://wiki.postgresql.org/wiki/Introduction_to_VACUUM,_ANALYZE,_EXPLAIN,_and_COUNT#COUNT.28.2A.29
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To provide context, this was adopted from an existing pattern we already use for builds
:
server/database/postgres/build_list.go
Lines 89 to 113 in 3aa414e
// count the results | |
count, err := c.GetOrgBuildCount(org, filters) | |
if err != nil { | |
return builds, 0, err | |
} | |
// short-circuit if there are no results | |
if count == 0 { | |
return builds, 0, nil | |
} | |
// calculate offset for pagination through results | |
offset := perPage * (page - 1) | |
// send query to the database and store result in variable | |
err = c.Postgres. | |
Table(constants.TableBuild). | |
Select("builds.*"). | |
Joins("JOIN repos ON builds.repo_id = repos.id and repos.org = ?", org). | |
Where(filters). | |
Order("created DESC"). | |
Order("id"). | |
Limit(perPage). | |
Offset(offset). | |
Scan(b).Error |
And this code follows the same pattern used in the other database functions to list resources e.g.
- https://github.com/go-vela/server/blob/main/database/hook/list.go#L14
- https://github.com/go-vela/server/blob/main/database/repo/list.go#L14
- https://github.com/go-vela/server/blob/main/database/user/list.go#L14
In general, this need for the count stems from usage for API pagination.
Before I started the DB refactor efforts, we still called the count for API but did so in a separate function i.e.
Lines 241 to 259 in 8c2fdb2
// send API call to capture the total number of services for the build | |
t, err := database.FromContext(c).GetBuildServiceCount(b) | |
if err != nil { | |
retErr := fmt.Errorf("unable to get services count for build %s: %w", entry, err) | |
util.HandleError(c, http.StatusInternalServerError, retErr) | |
return | |
} | |
// send API call to capture the list of services for the build | |
s, err := database.FromContext(c).GetBuildServiceList(b, page, perPage) | |
if err != nil { | |
retErr := fmt.Errorf("unable to get services for build %s: %w", entry, err) | |
util.HandleError(c, http.StatusInternalServerError, retErr) | |
return | |
} |
I decided it was worth adopting the pattern setup for builds
since it reduces the need to call them separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I thought it was worth highlighting a statement from the document you linked:
- turns out I misread the article.
In general, calling count(*)
for a specific table isn't very taxing.
Could you elaborate on your concern?
Are you facing issues with this for other tables and that's why you're mentioning it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, I don't really have any issues with the implementation, nor are we experiencing performance problems. Though, COUNT
queries across a specific table without any WHERE
clause related to an index are relatively slow (or slower than you'd expect is probably a better descriptor): https://wiki.postgresql.org/wiki/Slow_Counting.
I'm fine moving this conversation elsewhere as a potential reconsideration of design since it's endemic across the code base, as you pointed out 👍
Just trying to give all my thoughts so I don't forget 😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure 👍 perhaps it's worth opening an issue for this so it doesn't get forgotten?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
xref: go-vela/community#538
Part of go-vela/community#772
Dependent on go-vela/types#289
This adds a new
schedule
package to thegithub.com/go-vela/server/database
package.This contains a
ScheduleInterface
interface declaring all functions necessary for schedule based interactions with the database:server/database/schedule/interface.go
Lines 12 to 49 in 32d83df
This package also contains the
engine
which implements the above schedule interface:server/database/schedule/schedule.go
Lines 23 to 37 in 32d83df
This
engine
contains no raw SQL queries for integrating with theschedules
table.Instead, we leverage our DB library's (https://gorm.io/) agnostic abstraction for integrating with that table.