don't lock all votes, but in scope only #77

This commit is contained in:
Umputun
2018-06-09 18:28:00 -05:00
parent 6bb5718e83
commit 1af8b672a5
2 changed files with 25 additions and 4 deletions
+25 -3
View File
@@ -18,7 +18,12 @@ type DataStore struct {
Secret string
MaxCommentSize int
lock sync.Mutex
// granular locks
scopedLocks struct {
sync.Mutex
sync.Once
locks map[string]sync.Locker
}
}
const defaultCommentMaxSize = 2000
@@ -56,8 +61,10 @@ func (s *DataStore) SetPin(locator store.Locator, commentID string, status bool)
// Vote for comment by id and locator
func (s *DataStore) Vote(locator store.Locator, commentID string, userID string, val bool) (comment store.Comment, err error) {
s.lock.Lock()
defer s.lock.Unlock()
cLock := s.getsScopedLocks(locator.URL) // get lock for URL scope
cLock.Lock()
defer cLock.Unlock()
comment, err = s.Get(locator, commentID)
if err != nil {
@@ -166,3 +173,18 @@ func (s *DataStore) IsVerifiedFn() func(siteID string, userID string) bool {
return s.IsVerified(siteID, userID)
}
}
// getsScopedLocks pull lock from the map if found or create a new one
func (s *DataStore) getsScopedLocks(id string) (lock sync.Locker) {
s.scopedLocks.Do(func() { s.scopedLocks.locks = map[string]sync.Locker{} })
s.scopedLocks.Lock()
lock, ok := s.scopedLocks.locks[id]
if !ok {
lock = &sync.Mutex{}
s.scopedLocks.locks[id] = lock
}
s.scopedLocks.Unlock()
return lock
}
-1
View File
@@ -200,7 +200,6 @@ func TestService_VoteConcurrent(t *testing.T) {
wg.Wait()
res, err = b.Last("radio-t", 0)
require.NoError(t, err)
t.Logf("%+v %d", res[0], res[0].Score)
assert.Equal(t, 1000, res[0].Score, "should have 1000 score")
assert.Equal(t, 1000, len(res[0].Votes), "should have 1000 votes")
}