Skip to content
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

Speed up HasUserStopwatch & GetActiveStopwatch #23051

Merged
merged 15 commits into from
Feb 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions models/issues/stopwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
Expand Down Expand Up @@ -132,12 +133,26 @@ func StopwatchExists(userID, issueID int64) bool {
}

// HasUserStopwatch returns true if the user has a stopwatch
func HasUserStopwatch(ctx context.Context, userID int64) (exists bool, sw *Stopwatch, err error) {
sw = new(Stopwatch)
func HasUserStopwatch(ctx context.Context, userID int64) (exists bool, sw *Stopwatch, issue *Issue, err error) {
type stopwatchIssueRepo struct {
Stopwatch `xorm:"extends"`
Issue `xorm:"extends"`
repo.Repository `xorm:"extends"`
}
zeripath marked this conversation as resolved.
Show resolved Hide resolved

swIR := new(stopwatchIssueRepo)
exists, err = db.GetEngine(ctx).
Table("stopwatch").
Where("user_id = ?", userID).
Get(sw)
return exists, sw, err
Join("INNER", "issue", "issue.id = stopwatch.issue_id").
Join("INNER", "repository", "repository.id = issue.repo_id").
Get(swIR)
if exists {
sw = &swIR.Stopwatch
issue = &swIR.Issue
issue.Repo = &swIR.Repository
}
return exists, sw, issue, err
}

// FinishIssueStopwatchIfPossible if stopwatch exist then finish it otherwise ignore
Expand Down Expand Up @@ -217,23 +232,18 @@ func CreateIssueStopwatch(ctx context.Context, user *user_model.User, issue *Iss
}

// if another stopwatch is running: stop it
exists, sw, err := HasUserStopwatch(ctx, user.ID)
exists, _, otherIssue, err := HasUserStopwatch(ctx, user.ID)
if err != nil {
return err
}
if exists {
issue, err := GetIssueByID(ctx, sw.IssueID)
if err != nil {
return err
}

if err := FinishIssueStopwatch(ctx, user, issue); err != nil {
if err := FinishIssueStopwatch(ctx, user, otherIssue); err != nil {
return err
}
}

// Create stopwatch
sw = &Stopwatch{
sw := &Stopwatch{
UserID: user.ID,
IssueID: issue.ID,
}
Expand Down
4 changes: 2 additions & 2 deletions models/issues/stopwatch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ func TestStopwatchExists(t *testing.T) {
func TestHasUserStopwatch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

exists, sw, err := issues_model.HasUserStopwatch(db.DefaultContext, 1)
exists, sw, _, err := issues_model.HasUserStopwatch(db.DefaultContext, 1)
assert.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, int64(1), sw.ID)

exists, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3)
exists, _, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3)
assert.NoError(t, err)
assert.False(t, exists)
}
Expand Down
15 changes: 3 additions & 12 deletions routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1432,25 +1432,16 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["IsStopwatchRunning"] = issues_model.StopwatchExists(ctx.Doer.ID, issue.ID)
if !ctx.Data["IsStopwatchRunning"].(bool) {
var exists bool
var sw *issues_model.Stopwatch
if exists, sw, err = issues_model.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil {
var swIssue *issues_model.Issue
if exists, _, swIssue, err = issues_model.HasUserStopwatch(ctx, ctx.Doer.ID); err != nil {
ctx.ServerError("HasUserStopwatch", err)
return
}
ctx.Data["HasUserStopwatch"] = exists
if exists {
// Add warning if the user has already a stopwatch
var otherIssue *issues_model.Issue
if otherIssue, err = issues_model.GetIssueByID(ctx, sw.IssueID); err != nil {
ctx.ServerError("GetIssueByID", err)
return
}
if err = otherIssue.LoadRepo(ctx); err != nil {
ctx.ServerError("LoadRepo", err)
return
}
// Add link to the issue of the already running stopwatch
ctx.Data["OtherStopwatchURL"] = otherIssue.Link()
ctx.Data["OtherStopwatchURL"] = swIssue.Link()
}
}
ctx.Data["CanUseTimetracker"] = ctx.Repo.CanUseTimetracker(issue, ctx.Doer)
Expand Down
14 changes: 1 addition & 13 deletions routers/web/repo/issue_stopwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func GetActiveStopwatch(ctx *context.Context) {
return
}

_, sw, err := issues_model.HasUserStopwatch(ctx, ctx.Doer.ID)
_, sw, issue, err := issues_model.HasUserStopwatch(ctx, ctx.Doer.ID)
if err != nil {
ctx.ServerError("HasUserStopwatch", err)
return
Expand All @@ -96,18 +96,6 @@ func GetActiveStopwatch(ctx *context.Context) {
return
}

issue, err := issues_model.GetIssueByID(ctx, sw.IssueID)
if err != nil || issue == nil {
if !issues_model.IsErrIssueNotExist(err) {
ctx.ServerError("GetIssueByID", err)
}
return
}
if err = issue.LoadRepo(ctx); err != nil {
ctx.ServerError("LoadRepo", err)
return
}

ctx.Data["ActiveStopwatch"] = StopwatchTmplInfo{
issue.Link(),
issue.Repo.FullName(),
Expand Down