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:
parent
89ca5ee823
commit
97fb4af723
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue