From 9a0a6f924ee84edade326e64d4a8223b17f9bae8 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Fri, 29 Sep 2017 11:21:06 -0700 Subject: [PATCH] prevent per-user concurrent sync --- .drone.yml | 19 +++++++++++++++++++ model/limit.go | 4 ++++ server/sync.go | 11 ++++++++--- server/user.go | 25 +++++++++++++++---------- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/.drone.yml b/.drone.yml index 2c1bc0603..9e3e59ee1 100644 --- a/.drone.yml +++ b/.drone.yml @@ -40,6 +40,7 @@ pipeline: publish_server_alpine: image: plugins/docker repo: drone/drone + dockerfile: Dockerfile.alpine secrets: [ docker_username, docker_password ] tag: [ alpine ] when: @@ -95,6 +96,24 @@ pipeline: branch: master event: push + release_server_alpine: + image: plugins/docker + repo: drone/drone + dockerfile: Dockerfile.alpine + secrets: [ docker_username, docker_password ] + tag: [ 0.8-alpine ] + when: + event: tag + + release_agent_alpine: + image: plugins/docker + repo: drone/agent + dockerfile: Dockerfile.agent.alpine + secrets: [ docker_username, docker_password ] + tag: [ 0.8-alpine ] + when: + event: tag + release_server: image: plugins/docker repo: drone/drone diff --git a/model/limit.go b/model/limit.go index 642e1f25b..46f50df19 100644 --- a/model/limit.go +++ b/model/limit.go @@ -6,6 +6,7 @@ package model type Limiter interface { LimitUser(*User) error LimitRepo(*User, *Repo) error + LimitRepos(*User, []*Repo) []*Repo LimitBuild(*User, *Repo, *Build) error } @@ -19,5 +20,8 @@ func (NoLimit) LimitUser(*User) error { return nil } // LimitRepo is a no-op for limiting repo creation. func (NoLimit) LimitRepo(*User, *Repo) error { return nil } +// LimitRepos is a no-op for limiting repository listings. +func (NoLimit) LimitRepos(user *User, repos []*Repo) []*Repo { return repos } + // LimitBuild is a no-op for limiting build creation. func (NoLimit) LimitBuild(*User, *Repo, *Build) error { return nil } diff --git a/server/sync.go b/server/sync.go index 899c9e0a1..9d42835f6 100644 --- a/server/sync.go +++ b/server/sync.go @@ -14,9 +14,10 @@ type Syncer interface { } type syncer struct { - remote remote.Remote - store store.Store - perms model.PermStore + remote remote.Remote + store store.Store + perms model.PermStore + limiter model.Limiter } func (s *syncer) Sync(user *model.User) error { @@ -26,6 +27,10 @@ func (s *syncer) Sync(user *model.User) error { return err } + if s.limiter != nil { + repos = s.limiter.LimitRepos(user, repos) + } + var perms []*model.Perm for _, repo := range repos { perm := model.Perm{ diff --git a/server/user.go b/server/user.go index 55cb202e8..00402ae71 100644 --- a/server/user.go +++ b/server/user.go @@ -27,17 +27,20 @@ func GetFeed(c *gin.Context) { if time.Unix(user.Synced, 0).Add(time.Hour * 72).Before(time.Now()) { logrus.Debugf("sync begin: %s", user.Login) + + user.Synced = time.Now().Unix() + store.FromContext(c).UpdateUser(user) + sync := syncer{ - remote: remote.FromContext(c), - store: store.FromContext(c), - perms: store.FromContext(c), + remote: remote.FromContext(c), + store: store.FromContext(c), + perms: store.FromContext(c), + limiter: Config.Services.Limiter, } if err := sync.Sync(user); err != nil { logrus.Debugf("sync error: %s: %s", user.Login, err) } else { logrus.Debugf("sync complete: %s", user.Login) - user.Synced = time.Now().Unix() - store.FromContext(c).UpdateUser(user) } } @@ -68,17 +71,19 @@ func GetRepos(c *gin.Context) { if flush || time.Unix(user.Synced, 0).Add(time.Hour*72).Before(time.Now()) { logrus.Debugf("sync begin: %s", user.Login) + user.Synced = time.Now().Unix() + store.FromContext(c).UpdateUser(user) + sync := syncer{ - remote: remote.FromContext(c), - store: store.FromContext(c), - perms: store.FromContext(c), + remote: remote.FromContext(c), + store: store.FromContext(c), + perms: store.FromContext(c), + limiter: Config.Services.Limiter, } if err := sync.Sync(user); err != nil { logrus.Debugf("sync error: %s: %s", user.Login, err) } else { logrus.Debugf("sync complete: %s", user.Login) - user.Synced = time.Now().Unix() - store.FromContext(c).UpdateUser(user) } }