Skip to content

Add commit count caching #2774

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

Merged
merged 5 commits into from
Oct 26, 2017
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
3 changes: 3 additions & 0 deletions conf/app.ini
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ INTERVAL = 60
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
; memcache: `127.0.0.1:11211`
HOST =
; Time to keep items in cache if not used, default is 16 hours.
; Setting it to 0 disables caching
ITEM_TTL = 16h

[session]
; Either "memory", "file", or "redis", default is "memory"
Expand Down
11 changes: 11 additions & 0 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,17 @@ func (repo *Repository) APIFormat(mode AccessMode) *api.Repository {
return repo.innerAPIFormat(mode, false)
}

// GetCommitsCountCacheKey returns cache key used for commits count caching.
func (repo *Repository) GetCommitsCountCacheKey(contextName string, isRef bool) string {
var prefix string
if isRef {
prefix = "ref"
} else {
prefix = "commit"
}
return fmt.Sprintf("commits-count-%d-%s-%s", repo.ID, prefix, contextName)
}

func (repo *Repository) innerAPIFormat(mode AccessMode, isParent bool) *api.Repository {
var parent *api.Repository

Expand Down
13 changes: 10 additions & 3 deletions models/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"strings"

"code.gitea.io/git"

"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/log"
)

Expand Down Expand Up @@ -205,19 +205,26 @@ func pushUpdate(opts PushUpdateOptions) (repo *Repository, err error) {
var commits = &PushCommits{}
if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
// If is tag reference
tagName := opts.RefFullName[len(git.TagPrefix):]
if isDelRef {
err = pushUpdateDeleteTag(repo, gitRepo, opts.RefFullName[len(git.TagPrefix):])
err = pushUpdateDeleteTag(repo, gitRepo, tagName)
if err != nil {
return nil, fmt.Errorf("pushUpdateDeleteTag: %v", err)
}
} else {
err = pushUpdateAddTag(repo, gitRepo, opts.RefFullName[len(git.TagPrefix):])
// Clear cache for tag commit count
cache.Remove(repo.GetCommitsCountCacheKey(tagName, true))
err = pushUpdateAddTag(repo, gitRepo, tagName)
if err != nil {
return nil, fmt.Errorf("pushUpdateAddTag: %v", err)
}
}
} else if !isDelRef {
// If is branch reference

// Clear cache for branch commit count
cache.Remove(repo.GetCommitsCountCacheKey(opts.RefFullName[len(git.BranchPrefix):], true))

newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
if err != nil {
return nil, fmt.Errorf("gitRepo.GetCommit: %v", err)
Expand Down
72 changes: 72 additions & 0 deletions modules/cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package cache

import (
"code.gitea.io/gitea/modules/setting"

mc "github.com/go-macaron/cache"
)

var conn mc.Cache

// NewContext start cache service
func NewContext() error {
if setting.CacheService == nil || conn != nil {
return nil
}

var err error
conn, err = mc.NewCacher(setting.CacheService.Adapter, mc.Options{
Adapter: setting.CacheService.Adapter,
AdapterConfig: setting.CacheService.Conn,
Interval: setting.CacheService.Interval,
})
return err
}

// GetInt returns key value from cache with callback when no key exists in cache
func GetInt(key string, getFunc func() (int, error)) (int, error) {
if conn == nil || setting.CacheService.TTL == 0 {
return getFunc()
}
if !conn.IsExist(key) {
var (
value int
err error
)
if value, err = getFunc(); err != nil {
return value, err
}
conn.Put(key, value, int64(setting.CacheService.TTL.Seconds()))
}
return conn.Get(key).(int), nil
}

// GetInt64 returns key value from cache with callback when no key exists in cache
func GetInt64(key string, getFunc func() (int64, error)) (int64, error) {
if conn == nil || setting.CacheService.TTL == 0 {
return getFunc()
}
if !conn.IsExist(key) {
var (
value int64
err error
)
if value, err = getFunc(); err != nil {
return value, err
}
conn.Put(key, value, int64(setting.CacheService.TTL.Seconds()))
}
return conn.Get(key).(int64), nil
}

// Remove key from cache
func Remove(key string) {
if conn == nil {
return
}
conn.Delete(key)
}
21 changes: 19 additions & 2 deletions modules/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (

"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/setting"

"github.com/Unknwon/com"
"gopkg.in/editorconfig/editorconfig-core-go.v1"
"gopkg.in/macaron.v1"
Expand Down Expand Up @@ -100,6 +102,21 @@ func (r *Repository) CanUseTimetracker(issue *models.Issue, user *models.User) b
r.IsWriter() || issue.IsPoster(user.ID) || issue.AssigneeID == user.ID)
}

// GetCommitsCount returns cached commit count for current view
func (r *Repository) GetCommitsCount() (int64, error) {
var contextName string
if r.IsViewBranch {
contextName = r.BranchName
} else if r.IsViewTag {
contextName = r.TagName
} else {
contextName = r.CommitID
}
return cache.GetInt64(r.Repository.GetCommitsCountCacheKey(contextName, r.IsViewBranch || r.IsViewTag), func() (int64, error) {
return r.Commit.CommitsCount()
})
}

// GetEditorconfig returns the .editorconfig definition if found in the
// HEAD of the default repo branch.
func (r *Repository) GetEditorconfig() (*editorconfig.Editorconfig, error) {
Expand Down Expand Up @@ -535,9 +552,9 @@ func RepoRef() macaron.Handler {
ctx.Data["IsViewCommit"] = ctx.Repo.IsViewCommit
ctx.Data["CanCreateBranch"] = ctx.Repo.CanCreateBranch()

ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
if err != nil {
ctx.Handle(500, "CommitsCount", err)
ctx.Handle(500, "GetCommitsCount", err)
return
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
Expand Down
32 changes: 22 additions & 10 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,6 @@ var (
// Time settings
TimeFormat string

// Cache settings
CacheAdapter string
CacheInterval int
CacheConn string

// Session settings
SessionConfig session.Options
CSRFCookieName = "_csrf"
Expand Down Expand Up @@ -1295,16 +1290,33 @@ func NewXORMLogService(disableConsole bool) {
}
}

// Cache represents cache settings
type Cache struct {
Adapter string
Interval int
Conn string
TTL time.Duration
}

var (
// CacheService the global cache
CacheService *Cache
)

func newCacheService() {
CacheAdapter = Cfg.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"})
switch CacheAdapter {
sec := Cfg.Section("cache")
CacheService = &Cache{
Adapter: sec.Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"}),
}
switch CacheService.Adapter {
case "memory":
CacheInterval = Cfg.Section("cache").Key("INTERVAL").MustInt(60)
CacheService.Interval = sec.Key("INTERVAL").MustInt(60)
case "redis", "memcache":
CacheConn = strings.Trim(Cfg.Section("cache").Key("HOST").String(), "\" ")
CacheService.Conn = strings.Trim(sec.Key("HOST").String(), "\" ")
default:
log.Fatal(4, "Unknown cache adapter: %s", CacheAdapter)
log.Fatal(4, "Unknown cache adapter: %s", CacheService.Adapter)
}
CacheService.TTL = sec.Key("ITEM_TTL").MustDuration(16 * time.Hour)

log.Info("Cache Service Enabled")
}
Expand Down
6 changes: 3 additions & 3 deletions routers/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ func Config(ctx *context.Context) {
ctx.Data["Mailer"] = setting.MailService
}

ctx.Data["CacheAdapter"] = setting.CacheAdapter
ctx.Data["CacheInterval"] = setting.CacheInterval
ctx.Data["CacheConn"] = setting.CacheConn
ctx.Data["CacheAdapter"] = setting.CacheService.Adapter
ctx.Data["CacheInterval"] = setting.CacheService.Interval
ctx.Data["CacheConn"] = setting.CacheService.Conn

ctx.Data["SessionConfig"] = setting.SessionConfig

Expand Down
3 changes: 3 additions & 0 deletions routers/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import (
"code.gitea.io/git"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/cron"
"code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/mailer"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/ssh"

macaron "gopkg.in/macaron.v1"
)

Expand All @@ -37,6 +39,7 @@ func checkRunMode() {
func NewServices() {
setting.NewServices()
mailer.NewContext()
cache.NewContext()
}

// GlobalInit is for global configuration reload-able.
Expand Down
4 changes: 2 additions & 2 deletions routers/repo/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func Commits(ctx *context.Context) {
}
ctx.Data["PageIsViewCode"] = true

commitsCount, err := ctx.Repo.Commit.CommitsCount()
commitsCount, err := ctx.Repo.GetCommitsCount()
if err != nil {
ctx.Handle(500, "GetCommitsCount", err)
return
Expand Down Expand Up @@ -91,7 +91,7 @@ func Graph(ctx *context.Context) {
ctx.Data["PageIsCommits"] = true
ctx.Data["PageIsViewCode"] = true

commitsCount, err := ctx.Repo.Commit.CommitsCount()
commitsCount, err := ctx.Repo.GetCommitsCount()
if err != nil {
ctx.Handle(500, "GetCommitsCount", err)
return
Expand Down
10 changes: 5 additions & 5 deletions routers/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ func NewMacaron() *macaron.Macaron {
Redirect: true,
}))
m.Use(cache.Cacher(cache.Options{
Adapter: setting.CacheAdapter,
AdapterConfig: setting.CacheConn,
Interval: setting.CacheInterval,
Adapter: setting.CacheService.Adapter,
AdapterConfig: setting.CacheService.Conn,
Interval: setting.CacheService.Interval,
}))
m.Use(captcha.Captchaer(captcha.Options{
SubURL: setting.AppSubURL,
Expand Down Expand Up @@ -576,9 +576,9 @@ func RegisterRoutes(m *macaron.Macaron) {
ctx.Handle(500, "GetBranchCommit", err)
return
}
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
ctx.Repo.CommitsCount, err = ctx.Repo.GetCommitsCount()
if err != nil {
ctx.Handle(500, "CommitsCount", err)
ctx.Handle(500, "GetCommitsCount", err)
return
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
Expand Down