don't lock all votes, but in scope only #77
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user