Fix a bug where reloaded groups lost their CanSee data.

Remove a couple of redundant queries in group reload.
Exit from group reload early if there's an error.
Remove a couple of redundant assignments in the forum list.
Shorten some variable names.
This commit is contained in:
Azareal 2019-06-18 14:13:47 +10:00
parent 89ca5ee823
commit 97fb4af723
6 changed files with 74 additions and 74 deletions

View File

@ -166,35 +166,35 @@ func (fps *MemoryForumPermsStore) Reload(fid int) error {
}
// ! Throughput on this might be bad due to the excessive locking
func (fps *MemoryForumPermsStore) GetAllMap() (bigMap map[int]map[int]*ForumPerms) {
func (s *MemoryForumPermsStore) GetAllMap() (bigMap map[int]map[int]*ForumPerms) {
bigMap = make(map[int]map[int]*ForumPerms)
fps.evenLock.RLock()
for fid, subMap := range fps.evenForums {
s.evenLock.RLock()
for fid, subMap := range s.evenForums {
bigMap[fid] = subMap
}
fps.evenLock.RUnlock()
fps.oddLock.RLock()
for fid, subMap := range fps.oddForums {
s.evenLock.RUnlock()
s.oddLock.RLock()
for fid, subMap := range s.oddForums {
bigMap[fid] = subMap
}
fps.oddLock.RUnlock()
s.oddLock.RUnlock()
return bigMap
}
// TODO: Add a hook here and have plugin_guilds use it
// TODO: Check if the forum exists?
// TODO: Fix the races
func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) {
func (s *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) {
var fmap map[int]*ForumPerms
var ok bool
if fid%2 == 0 {
fps.evenLock.RLock()
fmap, ok = fps.evenForums[fid]
fps.evenLock.RUnlock()
s.evenLock.RLock()
fmap, ok = s.evenForums[fid]
s.evenLock.RUnlock()
} else {
fps.oddLock.RLock()
fmap, ok = fps.oddForums[fid]
fps.oddLock.RUnlock()
s.oddLock.RLock()
fmap, ok = s.oddForums[fid]
s.oddLock.RUnlock()
}
if !ok {
return fperms, ErrNoRows
@ -209,8 +209,8 @@ func (fps *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err
// TODO: Check if the forum exists?
// TODO: Fix the races
func (fps *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) {
fPermsPtr, err := fps.Get(fid, gid)
func (s *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) {
fPermsPtr, err := s.Get(fid, gid)
if err != nil {
return fperms, err
}

View File

@ -8,6 +8,7 @@ import (
"log"
"sort"
"sync"
"strconv"
"github.com/Azareal/Gosora/query_gen"
)
@ -95,8 +96,8 @@ func (mgs *MemoryGroupStore) LoadGroups() error {
}
// TODO: Hit the database when the item isn't in memory
func (mgs *MemoryGroupStore) dirtyGetUnsafe(gid int) *Group {
group, ok := mgs.groups[gid]
func (s *MemoryGroupStore) dirtyGetUnsafe(gid int) *Group {
group, ok := s.groups[gid]
if !ok {
return &blankGroup
}
@ -104,10 +105,10 @@ func (mgs *MemoryGroupStore) dirtyGetUnsafe(gid int) *Group {
}
// TODO: Hit the database when the item isn't in memory
func (mgs *MemoryGroupStore) DirtyGet(gid int) *Group {
mgs.RLock()
group, ok := mgs.groups[gid]
mgs.RUnlock()
func (s *MemoryGroupStore) DirtyGet(gid int) *Group {
s.RLock()
group, ok := s.groups[gid]
s.RUnlock()
if !ok {
return &blankGroup
}
@ -115,10 +116,10 @@ func (mgs *MemoryGroupStore) DirtyGet(gid int) *Group {
}
// TODO: Hit the database when the item isn't in memory
func (mgs *MemoryGroupStore) Get(gid int) (*Group, error) {
mgs.RLock()
group, ok := mgs.groups[gid]
mgs.RUnlock()
func (s *MemoryGroupStore) Get(gid int) (*Group, error) {
s.RLock()
group, ok := s.groups[gid]
s.RUnlock()
if !ok {
return nil, ErrNoRows
}
@ -126,38 +127,49 @@ func (mgs *MemoryGroupStore) Get(gid int) (*Group, error) {
}
// TODO: Hit the database when the item isn't in memory
func (mgs *MemoryGroupStore) GetCopy(gid int) (Group, error) {
mgs.RLock()
group, ok := mgs.groups[gid]
mgs.RUnlock()
func (s *MemoryGroupStore) GetCopy(gid int) (Group, error) {
s.RLock()
group, ok := s.groups[gid]
s.RUnlock()
if !ok {
return blankGroup, ErrNoRows
}
return *group, nil
}
func (mgs *MemoryGroupStore) Reload(id int) error {
var group = &Group{ID: id}
err := mgs.get.QueryRow(id).Scan(&group.Name, &group.PermissionsText, &group.PluginPermsText, &group.IsMod, &group.IsAdmin, &group.IsBanned, &group.Tag)
func (s *MemoryGroupStore) Reload(id int) error {
// TODO: Reload this data too
group, err := s.Get(id)
if err != nil {
LogError(errors.New("can't get cansee data for group #" + strconv.Itoa(id)))
return nil
}
canSee := group.CanSee
group = &Group{ID: id, CanSee: canSee}
err = s.get.QueryRow(id).Scan(&group.Name, &group.PermissionsText, &group.PluginPermsText, &group.IsMod, &group.IsAdmin, &group.IsBanned, &group.Tag)
if err != nil {
return err
}
err = mgs.initGroup(group)
err = s.initGroup(group)
if err != nil {
LogError(err)
return nil
}
mgs.CacheSet(group)
err = RebuildGroupPermissions(id)
// TODO: Do we really need this?
/*err = RebuildGroupPermissions(group)
if err != nil {
LogError(err)
}
return nil
}*/
s.CacheSet(group)
TopicListThaw.Thaw()
return nil
}
func (mgs *MemoryGroupStore) initGroup(group *Group) error {
func (s *MemoryGroupStore) initGroup(group *Group) error {
err := json.Unmarshal(group.PermissionsText, &group.Perms)
if err != nil {
log.Printf("group: %+v\n", group)
@ -180,25 +192,25 @@ func (mgs *MemoryGroupStore) initGroup(group *Group) error {
group.IsBanned = false
}
err = mgs.userCount.QueryRow(group.ID).Scan(&group.UserCount)
err = s.userCount.QueryRow(group.ID).Scan(&group.UserCount)
if err != sql.ErrNoRows {
return err
}
return nil
}
func (mgs *MemoryGroupStore) CacheSet(group *Group) error {
mgs.Lock()
mgs.groups[group.ID] = group
mgs.Unlock()
func (s *MemoryGroupStore) CacheSet(group *Group) error {
s.Lock()
s.groups[group.ID] = group
s.Unlock()
return nil
}
// TODO: Hit the database when the item isn't in memory
func (mgs *MemoryGroupStore) Exists(gid int) bool {
mgs.RLock()
group, ok := mgs.groups[gid]
mgs.RUnlock()
func (s *MemoryGroupStore) Exists(gid int) bool {
s.RLock()
group, ok := s.groups[gid]
s.RUnlock()
return ok && group.Name != ""
}
@ -287,23 +299,23 @@ func (mgs *MemoryGroupStore) Create(name string, tag string, isAdmin bool, isMod
//return gid, TopicList.RebuildPermTree()
}
func (mgs *MemoryGroupStore) GetAll() (results []*Group, err error) {
func (s *MemoryGroupStore) GetAll() (results []*Group, err error) {
var i int
mgs.RLock()
results = make([]*Group, len(mgs.groups))
for _, group := range mgs.groups {
s.RLock()
results = make([]*Group, len(s.groups))
for _, group := range s.groups {
results[i] = group
i++
}
mgs.RUnlock()
s.RUnlock()
sort.Sort(SortGroup(results))
return results, nil
}
func (mgs *MemoryGroupStore) GetAllMap() (map[int]*Group, error) {
mgs.RLock()
defer mgs.RUnlock()
return mgs.groups, nil
func (s *MemoryGroupStore) GetAllMap() (map[int]*Group, error) {
s.RLock()
defer s.RUnlock()
return s.groups, nil
}
// ? - Set the lower and higher numbers to 0 to remove the bounds

View File

@ -171,7 +171,7 @@ func PresetToLang(preset string) string {
// TODO: Is this racey?
// TODO: Test this along with the rest of the perms system
func RebuildGroupPermissions(gid int) error {
func RebuildGroupPermissions(group *Group) error {
var permstr []byte
log.Print("Reloading a group")
@ -182,7 +182,7 @@ func RebuildGroupPermissions(gid int) error {
}
defer getGroupPerms.Close()
err = getGroupPerms.QueryRow(gid).Scan(&permstr)
err = getGroupPerms.QueryRow(group.ID).Scan(&permstr)
if err != nil {
return err
}
@ -194,11 +194,6 @@ func RebuildGroupPermissions(gid int) error {
if err != nil {
return err
}
group, err := Groups.Get(gid)
if err != nil {
return err
}
group.Perms = tmpPerms
return nil
}

View File

@ -13,14 +13,13 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
if skip || rerr != nil {
return rerr
}
header.Title = phrases.GetTitlePhrase("forums")
header.Zone = "forums"
header.Path = "/forums/"
header.MetaDesc = header.Settings["meta_desc"].(string)
var err error
var forumList []c.Forum
var canSee []int
if user.IsSuperAdmin {
canSee, err = c.Forums.GetAllVisibleIDs()
@ -36,6 +35,7 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
canSee = group.CanSee
}
var forumList []c.Forum
for _, fid := range canSee {
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
var forum = c.Forums.DirtyGet(fid).Copy()
@ -43,11 +43,7 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
if forum.LastTopicID != 0 {
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
forum.LastTopicTime = c.RelativeTime(forum.LastTopic.LastReplyAt)
} else {
forum.LastTopicTime = ""
}
} else {
forum.LastTopicTime = ""
}
header.Hooks.Hook("forums_frow_assign", &forum)
forumList = append(forumList, forum)

View File

@ -131,7 +131,6 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
@ -211,7 +210,6 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}
@ -300,7 +298,6 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User,
} else if err != nil {
return c.InternalError(err, w, r)
}
if group.IsAdmin && !user.Perms.EditGroupAdmin {
return c.LocalError(phrases.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user)
}

View File

@ -94,7 +94,7 @@
<button form="quick_post_form" name="reply-button" class="formbutton">{{lang "topic.reply_button"}}</button>
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "topic.reply_add_poll_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" style="display: none;" />
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" style="display:none;" />
<label for="upload_files" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
<div id="upload_file_dock"></div>{{end}}
</div>