Shortening some things.

Fix the ordering of the lock in WsHubImpl.GuestCount.
This commit is contained in:
Azareal 2019-10-02 07:06:22 +10:00
parent 85b0522955
commit ff48ec9d86
14 changed files with 232 additions and 240 deletions

View File

@ -198,7 +198,7 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
return err
}
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid, fid, preset, permissions", "?,?,?,?")
addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid,fid,preset,permissions", "?,?,?,?")
if err != nil {
return err
}
@ -222,19 +222,19 @@ func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string,
// TODO: Refactor this and write tests for it
// TODO: We really need to improve the thread safety of this
func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
if !fperms.Overrides {
func ForumPermsToGroupForumPreset(fp *ForumPerms) string {
if !fp.Overrides {
return "default"
}
if !fperms.ViewTopic {
if !fp.ViewTopic {
return "no_access"
}
canPost := (fperms.LikeItem && fperms.CreateTopic && fperms.CreateReply)
canModerate := (canPost && fperms.EditTopic && fperms.DeleteTopic && fperms.EditReply && fperms.DeleteReply && fperms.PinTopic && fperms.CloseTopic && fperms.MoveTopic)
canPost := (fp.LikeItem && fp.CreateTopic && fp.CreateReply)
canModerate := (canPost && fp.EditTopic && fp.DeleteTopic && fp.EditReply && fp.DeleteReply && fp.PinTopic && fp.CloseTopic && fp.MoveTopic)
if canModerate {
return "can_moderate"
}
if fperms.EditTopic || fperms.DeleteTopic || fperms.EditReply || fperms.DeleteReply || fperms.PinTopic || fperms.CloseTopic || fperms.MoveTopic {
if fp.EditTopic || fp.DeleteTopic || fp.EditReply || fp.DeleteReply || fp.PinTopic || fp.CloseTopic || fp.MoveTopic {
//if !canPost {
return "custom"
//}
@ -244,7 +244,7 @@ func ForumPermsToGroupForumPreset(fperms *ForumPerms) string {
if canPost {
return "can_post"
}
if fperms.ViewTopic && !fperms.LikeItem && !fperms.CreateTopic && !fperms.CreateReply {
if fp.ViewTopic && !fp.LikeItem && !fp.CreateTopic && !fp.CreateReply {
return "read_only"
}
return "custom"

View File

@ -35,9 +35,9 @@ func NewSQLSearcher(acc *qgen.Accumulator) (*SQLSearcher, error) {
}, acc.FirstError()
}
func (search *SQLSearcher) queryAll(q string) ([]int, error) {
func (s *SQLSearcher) queryAll(q string) ([]int, error) {
var ids []int
var run = func(stmt *sql.Stmt, q ...interface{}) error {
run := func(stmt *sql.Stmt, q ...interface{}) error {
rows, err := stmt.Query(q...)
if err == sql.ErrNoRows {
return nil
@ -57,11 +57,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
return rows.Err()
}
err := run(search.queryReplies, q)
err := run(s.queryReplies, q)
if err != nil {
return nil, err
}
err = run(search.queryTopics, q, q)
err = run(s.queryTopics, q, q)
if err != nil {
return nil, err
}
@ -71,11 +71,11 @@ func (search *SQLSearcher) queryAll(q string) ([]int, error) {
return ids, err
}
func (search *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
func (s *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
if len(zones) == 0 {
return nil, nil
}
var run = func(rows *sql.Rows, err error) error {
run := func(rows *sql.Rows, err error) error {
if err == sql.ErrNoRows {
return nil
} else if err != nil {
@ -95,7 +95,7 @@ func (search *SQLSearcher) Query(q string, zones []int) (ids []int, err error) {
}
if len(zones) == 1 {
err = run(search.queryZone.Query(q, q, q, zones[0]))
err = run(s.queryZone.Query(q, q, q, zones[0]))
} else {
var zList string
for _, zone := range zones {
@ -128,6 +128,6 @@ func NewElasticSearchSearcher() (*ElasticSearchSearcher, error) {
return &ElasticSearchSearcher{}, nil
}
func (search *ElasticSearchSearcher) Query(q string, zones []int) ([]int, error) {
func (s *ElasticSearchSearcher) Query(q string, zones []int) ([]int, error) {
return nil, nil
}

View File

@ -53,7 +53,6 @@ func init() {
func NewThemeList() (themes ThemeList, err error) {
themes = make(map[string]*Theme)
themeFiles, err := ioutil.ReadDir("./themes")
if err != nil {
return themes, err
@ -76,7 +75,7 @@ func NewThemeList() (themes ThemeList, err error) {
return themes, err
}
var theme = &Theme{Name: ""}
theme := &Theme{Name: ""}
err = json.Unmarshal(themeFile, theme)
if err != nil {
return themes, err
@ -151,7 +150,7 @@ func NewThemeList() (themes ThemeList, err error) {
if override.IsDir() {
continue
}
var ext = filepath.Ext(themePath + "/overrides/" + override.Name())
ext := filepath.Ext(themePath + "/overrides/" + override.Name())
log.Print("attempting to add " + themePath + "/overrides/" + override.Name())
if ext != ".html" {
log.Print("not a html file")
@ -192,7 +191,7 @@ func NewThemeList() (themes ThemeList, err error) {
// TODO: Make the initThemes and LoadThemes functions less confusing
// ? - Delete themes which no longer exist in the themes folder from the database?
func (themes ThemeList) LoadActiveStatus() error {
func (t ThemeList) LoadActiveStatus() error {
ChangeDefaultThemeMutex.Lock()
defer ChangeDefaultThemeMutex.Unlock()
@ -211,7 +210,7 @@ func (themes ThemeList) LoadActiveStatus() error {
}
// Was the theme deleted at some point?
theme, ok := themes[uname]
theme, ok := t[uname]
if !ok {
continue
}
@ -226,13 +225,13 @@ func (themes ThemeList) LoadActiveStatus() error {
theme.Active = false
}
themes[uname] = theme
t[uname] = theme
}
return rows.Err()
}
func (themes ThemeList) LoadStaticFiles() error {
for _, theme := range themes {
func (t ThemeList) LoadStaticFiles() error {
for _, theme := range t {
err := theme.LoadStaticFiles()
if err != nil {
return err

View File

@ -290,10 +290,10 @@ var adminStatsMutex sync.RWMutex
func adminStatsTicker() {
time.Sleep(time.Second)
var lastUonline = -1
var lastGonline = -1
var lastTotonline = -1
var lastCPUPerc = -1
lastUonline := -1
lastGonline := -1
lastTotonline := -1
lastCPUPerc := -1
var lastAvailableRAM int64 = -1
var noStatUpdates, noRAMUpdates bool

View File

@ -32,9 +32,9 @@ func widgetSearchAndFilter(widget *Widget, hvars interface{}) (out string, err e
}
for _, fid := range canSee {
forum := Forums.DirtyGet(fid)
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
forums = append(forums, filterForum{forum, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == forum.ID})
f := Forums.DirtyGet(fid)
if f.ParentID == 0 && f.Name != "" && f.Active {
forums = append(forums, filterForum{f, (header.Zone == "view_forum" || header.Zone == "topics") && header.ZoneID == f.ID})
}
}

View File

@ -2,9 +2,9 @@ package common
import (
"encoding/json"
"log"
"sync"
"time"
"log"
"github.com/gorilla/websocket"
)
@ -38,7 +38,7 @@ func init() {
}
}
func (hub *WsHubImpl) Start() {
func (h *WsHubImpl) Start() {
log.Print("Setting up the WebSocket ticks")
ticker := time.NewTicker(time.Minute * 5)
defer func() {
@ -47,9 +47,9 @@ func (hub *WsHubImpl) Start() {
go func() {
for {
item := func(lock *sync.RWMutex, userMap map[int]*WSUser) {
lock.RLock()
defer lock.RUnlock()
item := func(l *sync.RWMutex, userMap map[int]*WSUser) {
l.RLock()
defer l.RUnlock()
// TODO: Copy to temporary slice for less contention?
for _, user := range userMap {
user.Ping()
@ -57,40 +57,40 @@ func (hub *WsHubImpl) Start() {
}
select {
case <-ticker.C:
item(&hub.evenUserLock, hub.evenOnlineUsers)
item(&hub.oddUserLock, hub.oddOnlineUsers)
item(&h.evenUserLock, h.evenOnlineUsers)
item(&h.oddUserLock, h.oddOnlineUsers)
}
}
}()
if Config.DisableLiveTopicList {
return
}
hub.lastTick = time.Now()
AddScheduledSecondTask(hub.Tick)
h.lastTick = time.Now()
AddScheduledSecondTask(h.Tick)
}
// This Tick is separate from the admin one, as we want to process that in parallel with this due to the blocking calls to gopsutil
func (hub *WsHubImpl) Tick() error {
return wsTopicListTick(hub)
func (h *WsHubImpl) Tick() error {
return wsTopicListTick(h)
}
func wsTopicListTick(hub *WsHubImpl) error {
func wsTopicListTick(h *WsHubImpl) error {
// Avoid hitting GetList when the topic list hasn't changed
if !TopicListThaw.Thawed() && hub.lastTopicList != nil {
if !TopicListThaw.Thawed() && h.lastTopicList != nil {
return nil
}
tickStart := time.Now()
// Don't waste CPU time if nothing has happened
// TODO: Get a topic list method which strips stickies?
tList, _, _, err := TopicList.GetList(1, "", nil)
if err != nil {
hub.lastTick = tickStart
h.lastTick = tickStart
return err // TODO: Do we get ErrNoRows here?
}
defer func() {
hub.lastTick = tickStart
hub.lastTopicList = tList
h.lastTick = tickStart
h.lastTopicList = tList
}()
if len(tList) == 0 {
return nil
@ -99,11 +99,11 @@ func wsTopicListTick(hub *WsHubImpl) error {
// TODO: Optimise this by only sniffing the top non-sticky
// TODO: Optimise this by getting back an unsorted list so we don't have to hop around the stickies
// TODO: Add support for new stickies / replies to them
if len(tList) == len(hub.lastTopicList) {
var hasItem = false
if len(tList) == len(h.lastTopicList) {
hasItem := false
for j, tItem := range tList {
if !tItem.Sticky {
if tItem.ID != hub.lastTopicList[j].ID || !tItem.LastReplyAt.Equal(hub.lastTopicList[j].LastReplyAt) {
if tItem.ID != h.lastTopicList[j].ID || !tItem.LastReplyAt.Equal(h.lastTopicList[j].LastReplyAt) {
hasItem = true
}
}
@ -122,9 +122,9 @@ func wsTopicListTick(hub *WsHubImpl) error {
}
// Copy these over so we close this loop as fast as possible so we can release the read lock, especially if the group gets are backed by calls to the database
var groupIDs = make(map[int]bool)
var currentWatchers = make([]*WSUser, len(topicListWatchers))
var i = 0
groupIDs := make(map[int]bool)
currentWatchers := make([]*WSUser, len(topicListWatchers))
i := 0
for wsUser, _ := range topicListWatchers {
currentWatchers[i] = wsUser
groupIDs[wsUser.User.Group] = true
@ -132,8 +132,8 @@ func wsTopicListTick(hub *WsHubImpl) error {
}
topicListMutex.RUnlock()
var groups = make(map[int]*Group)
var canSeeMap = make(map[string][]int)
groups := make(map[int]*Group)
canSeeMap := make(map[string][]int)
for groupID, _ := range groupIDs {
group, err := Groups.Get(groupID)
if err != nil {
@ -142,14 +142,14 @@ func wsTopicListTick(hub *WsHubImpl) error {
}
groups[group.ID] = group
var canSee = make([]byte, len(group.CanSee))
canSee := make([]byte, len(group.CanSee))
for i, item := range group.CanSee {
canSee[i] = byte(item)
}
canSeeMap[string(canSee)] = group.CanSee
}
var canSeeRenders = make(map[string][]byte)
canSeeRenders := make(map[string][]byte)
for name, canSee := range canSeeMap {
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "", nil)
if err != nil {
@ -161,7 +161,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
_ = forumList // Might use this later after we get the base feature working
if topicList[0].Sticky {
var lastSticky = 0
lastSticky := 0
for i, row := range topicList {
if !row.Sticky {
lastSticky = i
@ -175,7 +175,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
}
// TODO: Compare to previous tick to eliminate unnecessary work and data
var wsTopicList = make([]*WsTopicsRow, len(topicList))
wsTopicList := make([]*WsTopicsRow, len(topicList))
for i, topicRow := range topicList {
wsTopicList[i] = topicRow.WebSockets()
}
@ -191,7 +191,7 @@ func wsTopicListTick(hub *WsHubImpl) error {
//fmt.Println("writing to the clients")
for _, wsUser := range currentWatchers {
group := groups[wsUser.User.Group]
var canSee = make([]byte, len(group.CanSee))
canSee := make([]byte, len(group.CanSee))
for i, item := range group.CanSee {
canSee[i] = byte(item)
}
@ -213,38 +213,39 @@ func wsTopicListTick(hub *WsHubImpl) error {
return nil
}
func (hub *WsHubImpl) GuestCount() int {
defer hub.GuestLock.RUnlock()
hub.GuestLock.RLock()
return len(hub.OnlineGuests)
func (h *WsHubImpl) GuestCount() int {
h.GuestLock.RLock()
defer h.GuestLock.RUnlock()
return len(h.OnlineGuests)
}
func (hub *WsHubImpl) UserCount() (count int) {
hub.evenUserLock.RLock()
count += len(hub.evenOnlineUsers)
hub.evenUserLock.RUnlock()
hub.oddUserLock.RLock()
count += len(hub.oddOnlineUsers)
hub.oddUserLock.RUnlock()
func (h *WsHubImpl) UserCount() (count int) {
h.evenUserLock.RLock()
count += len(h.evenOnlineUsers)
h.evenUserLock.RUnlock()
h.oddUserLock.RLock()
count += len(h.oddOnlineUsers)
h.oddUserLock.RUnlock()
return count
}
func (hub *WsHubImpl) HasUser(uid int) (exists bool) {
hub.evenUserLock.RLock()
_, exists = hub.evenOnlineUsers[uid]
hub.evenUserLock.RUnlock()
func (h *WsHubImpl) HasUser(uid int) (exists bool) {
h.evenUserLock.RLock()
_, exists = h.evenOnlineUsers[uid]
h.evenUserLock.RUnlock()
if exists {
return exists
}
hub.oddUserLock.RLock()
_, exists = hub.oddOnlineUsers[uid]
hub.oddUserLock.RUnlock()
h.oddUserLock.RLock()
_, exists = h.oddOnlineUsers[uid]
h.oddUserLock.RUnlock()
return exists
}
func (hub *WsHubImpl) broadcastMessage(msg string) error {
var userLoop = func(users map[int]*WSUser, mutex *sync.RWMutex) error {
defer mutex.RUnlock()
func (h *WsHubImpl) broadcastMessage(msg string) error {
userLoop := func(users map[int]*WSUser, m *sync.RWMutex) error {
m.RLock()
defer m.RUnlock()
for _, wsUser := range users {
err := wsUser.WriteAll(msg)
if err != nil {
@ -254,25 +255,23 @@ func (hub *WsHubImpl) broadcastMessage(msg string) error {
return nil
}
// TODO: Can we move this RLock inside the closure safely?
hub.evenUserLock.RLock()
err := userLoop(hub.evenOnlineUsers, &hub.evenUserLock)
err := userLoop(h.evenOnlineUsers, &h.evenUserLock)
if err != nil {
return err
}
hub.oddUserLock.RLock()
return userLoop(hub.oddOnlineUsers, &hub.oddUserLock)
return userLoop(h.oddOnlineUsers, &h.oddUserLock)
}
func (hub *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
func (h *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
var ok bool
if uid%2 == 0 {
hub.evenUserLock.RLock()
wsUser, ok = hub.evenOnlineUsers[uid]
hub.evenUserLock.RUnlock()
h.evenUserLock.RLock()
wsUser, ok = h.evenOnlineUsers[uid]
h.evenUserLock.RUnlock()
} else {
hub.oddUserLock.RLock()
wsUser, ok = hub.oddOnlineUsers[uid]
hub.oddUserLock.RUnlock()
h.oddUserLock.RLock()
wsUser, ok = h.oddOnlineUsers[uid]
h.oddUserLock.RUnlock()
}
if !ok {
return nil, errWsNouser
@ -281,20 +280,20 @@ func (hub *WsHubImpl) getUser(uid int) (wsUser *WSUser, err error) {
}
// Warning: For efficiency, some of the *WSUsers may be nil pointers, DO NOT EXPORT
func (hub *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
func (h *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
if len(uids) == 0 {
return nil, errWsNouser
}
var appender = func(lock *sync.RWMutex, users map[int]*WSUser) {
lock.RLock()
defer lock.RUnlock()
appender := func(l *sync.RWMutex, users map[int]*WSUser) {
l.RLock()
defer l.RUnlock()
// We don't want to keep a lock on this for too long, so we'll accept some nil pointers
for _, uid := range uids {
wsUsers = append(wsUsers, users[uid])
}
}
appender(&hub.evenUserLock, hub.evenOnlineUsers)
appender(&hub.oddUserLock, hub.oddOnlineUsers)
appender(&h.evenUserLock, h.evenOnlineUsers)
appender(&h.oddUserLock, h.oddOnlineUsers)
if len(wsUsers) == 0 {
return nil, errWsNouser
}
@ -302,32 +301,32 @@ func (hub *WsHubImpl) getUsers(uids []int) (wsUsers []*WSUser, err error) {
}
// For Widget WOL, please avoid using this as it might wind up being really long and slow without the right safeguards
func (hub *WsHubImpl) AllUsers() (users []*User) {
var appender = func(lock *sync.RWMutex, userMap map[int]*WSUser) {
lock.RLock()
defer lock.RUnlock()
func (h *WsHubImpl) AllUsers() (users []*User) {
appender := func(l *sync.RWMutex, userMap map[int]*WSUser) {
l.RLock()
defer l.RUnlock()
for _, user := range userMap {
users = append(users, user.User)
}
}
appender(&hub.evenUserLock, hub.evenOnlineUsers)
appender(&hub.oddUserLock, hub.oddOnlineUsers)
appender(&h.evenUserLock, h.evenOnlineUsers)
appender(&h.oddUserLock, h.oddOnlineUsers)
return users
}
func (hub *WsHubImpl) removeUser(uid int) {
func (h *WsHubImpl) removeUser(uid int) {
if uid%2 == 0 {
hub.evenUserLock.Lock()
delete(hub.evenOnlineUsers, uid)
hub.evenUserLock.Unlock()
h.evenUserLock.Lock()
delete(h.evenOnlineUsers, uid)
h.evenUserLock.Unlock()
} else {
hub.oddUserLock.Lock()
delete(hub.oddOnlineUsers, uid)
hub.oddUserLock.Unlock()
h.oddUserLock.Lock()
delete(h.oddOnlineUsers, uid)
h.oddUserLock.Unlock()
}
}
func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error) {
func (h *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error) {
if user.ID == 0 {
wsUser := new(WSUser)
wsUser.User = new(User)
@ -348,11 +347,11 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
var mutex *sync.RWMutex
var theMap map[int]*WSUser
if user.ID%2 == 0 {
mutex = &hub.evenUserLock
theMap = hub.evenOnlineUsers
mutex = &h.evenUserLock
theMap = h.evenOnlineUsers
} else {
mutex = &hub.oddUserLock
theMap = hub.oddOnlineUsers
mutex = &h.oddUserLock
theMap = h.oddOnlineUsers
}
mutex.Lock()
@ -370,25 +369,25 @@ func (hub *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error)
return wsUser, nil
}
func (hub *WsHubImpl) RemoveConn(wsUser *WSUser, conn *websocket.Conn) {
func (h *WsHubImpl) RemoveConn(wsUser *WSUser, conn *websocket.Conn) {
wsUser.RemoveSocket(conn)
wsUser.Lock()
if len(wsUser.Sockets) == 0 {
hub.removeUser(wsUser.User.ID)
h.removeUser(wsUser.User.ID)
}
wsUser.Unlock()
}
func (hub *WsHubImpl) PushMessage(targetUser int, msg string) error {
wsUser, err := hub.getUser(targetUser)
func (h *WsHubImpl) PushMessage(targetUser int, msg string) error {
wsUser, err := h.getUser(targetUser)
if err != nil {
return err
}
return wsUser.WriteAll(msg)
}
func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
wsUser, err := hub.getUser(targetUser)
func (h *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
wsUser, err := h.getUser(targetUser)
if err != nil {
return err
}
@ -399,8 +398,8 @@ func (hub *WsHubImpl) pushAlert(targetUser int, alert Alert) error {
return wsUser.WriteAll(astr)
}
func (hub *WsHubImpl) pushAlerts(users []int, alert Alert) error {
wsUsers, err := hub.getUsers(users)
func (h *WsHubImpl) pushAlerts(users []int, alert Alert) error {
wsUsers, err := h.getUsers(users)
if err != nil {
return err
}

View File

@ -22,8 +22,8 @@ type WSUserSocket struct {
Page string
}
func (wsUser *WSUser) Ping() error {
for _, socket := range wsUser.Sockets {
func (u *WSUser) Ping() error {
for _, socket := range u.Sockets {
if socket == nil {
continue
}
@ -36,9 +36,9 @@ func (wsUser *WSUser) Ping() error {
return nil
}
func (wsUser *WSUser) WriteAll(msg string) error {
func (u *WSUser) WriteAll(msg string) error {
msgbytes := []byte(msg)
for _, socket := range wsUser.Sockets {
for _, socket := range u.Sockets {
if socket == nil {
continue
}
@ -52,14 +52,14 @@ func (wsUser *WSUser) WriteAll(msg string) error {
return nil
}
func (wsUser *WSUser) WriteToPage(msg string, page string) error {
return wsUser.WriteToPageBytes([]byte(msg), page)
func (u *WSUser) WriteToPage(msg string, page string) error {
return u.WriteToPageBytes([]byte(msg), page)
}
// Inefficient as it looks for sockets for a page even if there are none
func (wsUser *WSUser) WriteToPageBytes(msg []byte, page string) error {
func (u *WSUser) WriteToPageBytes(msg []byte, page string) error {
var success bool
for _, socket := range wsUser.Sockets {
for _, socket := range u.Sockets {
if socket == nil {
continue
}
@ -80,34 +80,34 @@ func (wsUser *WSUser) WriteToPageBytes(msg []byte, page string) error {
return nil
}
func (wsUser *WSUser) AddSocket(conn *websocket.Conn, page string) {
wsUser.Lock()
func (u *WSUser) AddSocket(conn *websocket.Conn, page string) {
u.Lock()
// If the number of the sockets is small, then we can keep the size of the slice mostly static and just walk through it looking for empty slots
if len(wsUser.Sockets) < 6 {
for i, socket := range wsUser.Sockets {
if len(u.Sockets) < 6 {
for i, socket := range u.Sockets {
if socket == nil {
wsUser.Sockets[i] = &WSUserSocket{conn, page}
wsUser.Unlock()
//fmt.Printf("%+v\n", wsUser.Sockets)
u.Sockets[i] = &WSUserSocket{conn, page}
u.Unlock()
//fmt.Printf("%+v\n", u.Sockets)
return
}
}
}
wsUser.Sockets = append(wsUser.Sockets, &WSUserSocket{conn, page})
//fmt.Printf("%+v\n", wsUser.Sockets)
wsUser.Unlock()
u.Sockets = append(u.Sockets, &WSUserSocket{conn, page})
//fmt.Printf("%+v\n", u.Sockets)
u.Unlock()
}
func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) {
wsUser.Lock()
if len(wsUser.Sockets) < 6 {
for i, socket := range wsUser.Sockets {
func (u *WSUser) RemoveSocket(conn *websocket.Conn) {
u.Lock()
if len(u.Sockets) < 6 {
for i, socket := range u.Sockets {
if socket == nil {
continue
}
if socket.conn == conn {
wsUser.Sockets[i] = nil
wsUser.Unlock()
u.Sockets[i] = nil
u.Unlock()
//fmt.Printf("%+v\n", wsUser.Sockets)
return
}
@ -115,25 +115,25 @@ func (wsUser *WSUser) RemoveSocket(conn *websocket.Conn) {
}
var key int
for i, socket := range wsUser.Sockets {
for i, socket := range u.Sockets {
if socket.conn == conn {
key = i
break
}
}
wsUser.Sockets = append(wsUser.Sockets[:key], wsUser.Sockets[key+1:]...)
//fmt.Printf("%+v\n", wsUser.Sockets)
u.Sockets = append(u.Sockets[:key], u.Sockets[key+1:]...)
//fmt.Printf("%+v\n", u.Sockets)
wsUser.Unlock()
u.Unlock()
}
func (wsUser *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
func (u *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error {
if conn == nil {
return ErrInvalidSocket
}
wsUser.Lock()
for _, socket := range wsUser.Sockets {
u.Lock()
for _, socket := range u.Sockets {
if socket == nil {
continue
}
@ -141,15 +141,15 @@ func (wsUser *WSUser) SetPageForSocket(conn *websocket.Conn, page string) error
socket.Page = page
}
}
wsUser.Unlock()
u.Unlock()
return nil
}
func (wsUser *WSUser) InPage(page string) bool {
wsUser.Lock()
defer wsUser.Unlock()
for _, socket := range wsUser.Sockets {
func (u *WSUser) InPage(page string) bool {
u.Lock()
defer u.Unlock()
for _, socket := range u.Sockets {
if socket == nil {
continue
}
@ -160,10 +160,10 @@ func (wsUser *WSUser) InPage(page string) bool {
return false
}
func (wsUser *WSUser) FinalizePage(page string, handle func()) {
wsUser.Lock()
defer wsUser.Unlock()
for _, socket := range wsUser.Sockets {
func (u *WSUser) FinalizePage(page string, handle func()) {
u.Lock()
defer u.Unlock()
for _, socket := range u.Sockets {
if socket == nil {
continue
}

View File

@ -37,7 +37,7 @@ func SitemapXml(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
sitemapItem := func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
@ -72,10 +72,10 @@ var fuzzySitemapRoutes = map[string]FuzzyRoute{
}
func sitemapSwitch(w http.ResponseWriter, r *http.Request) c.RouteError {
var path = r.URL.Path[len("/sitemaps/"):]
path := r.URL.Path[len("/sitemaps/"):]
for name, fuzzy := range fuzzySitemapRoutes {
if strings.HasPrefix(path, name) && strings.HasSuffix(path, ".xml") {
var spath = strings.TrimPrefix(path, name)
spath := strings.TrimPrefix(path, name)
spath = strings.TrimSuffix(spath, ".xml")
page, err := strconv.Atoi(spath)
if err != nil {
@ -99,7 +99,7 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
sitemapItem := func(path string) {
w.Write([]byte(`<url>
<loc>http` + sslBit + `://` + c.Site.URL + path + `</loc>
</url>
@ -116,9 +116,9 @@ func SitemapForums(w http.ResponseWriter, r *http.Request) c.RouteError {
for _, fid := range group.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()
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
sitemapItem(c.BuildForumURL(c.NameToSlug(forum.Name), forum.ID))
f := c.Forums.DirtyGet(fid).Copy()
if f.ParentID == 0 && f.Name != "" && f.Active {
sitemapItem(c.BuildForumURL(c.NameToSlug(f.Name), f.ID))
}
}
@ -133,7 +133,7 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl {
sslBit = "s"
}
var sitemapItem = func(path string) {
sitemapItem := func(path string) {
w.Write([]byte(`<sitemap>
<loc>http` + sslBit + `://` + c.Site.URL + "/" + path + `</loc>
</sitemap>
@ -158,7 +158,7 @@ func SitemapTopics(w http.ResponseWriter, r *http.Request) c.RouteError {
return c.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap
pageCount := topicCount / sitemapPageCap
//log.Print("topicCount", topicCount)
//log.Print("pageCount", pageCount)
writeXMLHeader(w, r)
@ -201,7 +201,7 @@ func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) c.RouteError
return c.InternalErrorXML(err, w, r)
}
var pageCount = topicCount / sitemapPageCap
pageCount := topicCount / sitemapPageCap
//log.Print("topicCount", topicCount)
//log.Print("pageCount", pageCount)
//log.Print("page",page)
@ -243,7 +243,6 @@ func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
w.Header().Set("Cache-Control", "private")
me := JsonMe{(&user).Me(), MeSite{c.Site.MaxRequestSize}}
jsonBytes, err := json.Marshal(me)
if err != nil {
return c.InternalErrorJS(err, w, r)
@ -258,13 +257,13 @@ func OpenSearchXml(w http.ResponseWriter, r *http.Request) c.RouteError {
if c.Site.EnableSsl {
furl += "s"
}
furl += "://"+c.Site.URL
furl += "://" + c.Site.URL
w.Write([]byte(`<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>`+c.Site.Name+`</ShortName>
<ShortName>` + c.Site.Name + `</ShortName>
<InputEncoding>UTF-8</InputEncoding>
<Url type="text/html" template="`+furl+`/topics/?q={searchTerms}" />
<Url type="application/opensearchdescription+xml" rel="self" template="`+furl+`/opensearch.xml" />
<moz:SearchForm>`+furl+`</moz:SearchForm>
<Url type="text/html" template="` + furl + `/topics/?q={searchTerms}" />
<Url type="application/opensearchdescription+xml" rel="self" template="` + furl + `/opensearch.xml" />
<moz:SearchForm>` + furl + `</moz:SearchForm>
</OpenSearchDescription>`))
return nil
}

View File

@ -35,15 +35,15 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
return c.LocalError("Bad extension", w, r, user)
}
sectionID, err := strconv.Atoi(r.FormValue("sid"))
sid, err := strconv.Atoi(r.FormValue("sid"))
if err != nil {
return c.LocalError("The sectionID is not an integer", w, r, user)
return c.LocalError("The sid is not an integer", w, r, user)
}
sectionTable := r.FormValue("stype")
var originTable string
var originID, uploadedBy int
err = attachmentStmts.get.QueryRow(filename, sectionID, sectionTable).Scan(&sectionID, &sectionTable, &originID, &originTable, &uploadedBy, &filename)
err = attachmentStmts.get.QueryRow(filename, sid, sectionTable).Scan(&sid, &sectionTable, &originID, &originTable, &uploadedBy, &filename)
if err == sql.ErrNoRows {
return c.NotFound(w, r, nil)
} else if err != nil {
@ -51,7 +51,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
}
if sectionTable == "forums" {
_, ferr := c.SimpleForumUserCheck(w, r, &user, sectionID)
_, ferr := c.SimpleForumUserCheck(w, r, &user, sid)
if ferr != nil {
return ferr
}
@ -70,7 +70,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
w.Header().Set("Cache-Control", "max-age="+strconv.Itoa(int(c.Year)))
} else {
guest := c.GuestUser
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sectionID)
_, ferr := c.SimpleForumUserCheck(w, r, &guest, sid)
if ferr != nil {
return ferr
}

View File

@ -7,8 +7,8 @@ import (
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
p "github.com/Azareal/Gosora/common/phrases"
qgen "github.com/Azareal/Gosora/query_gen"
)
type ForumStmts struct {
@ -32,7 +32,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
page, _ := strconv.Atoi(r.FormValue("page"))
_, fid, err := ParseSEOURL(sfid)
if err != nil {
return c.SimpleError(phrases.GetErrorPhrase("url_id_must_be_integer"),w,r,header)
return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, header)
}
ferr := c.ForumUserCheck(header, w, r, &user, fid)
@ -66,23 +66,23 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
// TODO: Use something other than TopicsRow as we don't need to store the forum name and link on each and every topic item?
var topicList []*c.TopicsRow
var reqUserList = make(map[int]bool)
reqUserList := make(map[int]bool)
for rows.Next() {
var topicItem = c.TopicsRow{ID: 0}
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.LastReplyID, &topicItem.ParentID, &topicItem.ViewCount, &topicItem.PostCount, &topicItem.LikeCount)
t := c.TopicsRow{ID: 0}
err := rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreatedBy, &t.IsClosed, &t.Sticky, &t.CreatedAt, &t.LastReplyAt, &t.LastReplyBy, &t.LastReplyID, &t.ParentID, &t.ViewCount, &t.PostCount, &t.LikeCount)
if err != nil {
return c.InternalError(err, w, r)
}
topicItem.Link = c.BuildTopicURL(c.NameToSlug(topicItem.Title), topicItem.ID)
t.Link = c.BuildTopicURL(c.NameToSlug(t.Title), t.ID)
// TODO: Create a specialised function with a bit less overhead for getting the last page for a post count
_, _, lastPage := c.PageOffset(topicItem.PostCount, 1, c.Config.ItemsPerPage)
topicItem.LastPage = lastPage
_, _, lastPage := c.PageOffset(t.PostCount, 1, c.Config.ItemsPerPage)
t.LastPage = lastPage
header.Hooks.VhookNoRet("forum_trow_assign", &topicItem, &forum)
topicList = append(topicList, &topicItem)
reqUserList[topicItem.CreatedBy] = true
reqUserList[topicItem.LastReplyBy] = true
header.Hooks.VhookNoRet("forum_trow_assign", &t, &forum)
topicList = append(topicList, &t)
reqUserList[t.CreatedBy] = true
reqUserList[t.LastReplyBy] = true
}
err = rows.Err()
if err != nil {
@ -90,7 +90,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
}
// Convert the user ID map to a slice, then bulk load the users
var idSlice = make([]int, len(reqUserList))
idSlice := make([]int, len(reqUserList))
var i int
for userID := range reqUserList {
idSlice[i] = userID
@ -105,9 +105,9 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
// Second pass to the add the user data
// TODO: Use a pointer to TopicsRow instead of TopicsRow itself?
for _, topicItem := range topicList {
topicItem.Creator = userList[topicItem.CreatedBy]
topicItem.LastUser = userList[topicItem.LastReplyBy]
for _, t := range topicList {
t.Creator = userList[t.CreatedBy]
t.LastUser = userList[t.LastReplyBy]
}
header.Zone = "view_forum"
header.ZoneID = forum.ID
@ -128,8 +128,8 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
if tmpl == "" {
ferr = renderTemplate("forum", w, r, header, pi)
} else {
tmpl = "forum_"+tmpl
err = renderTemplate3(tmpl, tmpl,w, r, header, pi)
tmpl = "forum_" + tmpl
err = renderTemplate3(tmpl, tmpl, w, r, header, pi)
if err != nil {
ferr = renderTemplate("forum", w, r, header, pi)
}

View File

@ -15,7 +15,7 @@ func IPSearch(w http.ResponseWriter, r *http.Request, user c.User, header *c.Hea
}
// TODO: Reject IP Addresses with illegal characters
var ip = c.SanitiseSingleLine(r.FormValue("ip"))
ip := c.SanitiseSingleLine(r.FormValue("ip"))
uids, err := c.IPSearch.Lookup(ip)
if err != nil {
return c.InternalError(err, w, r)

View File

@ -81,7 +81,6 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user)
}
page, err := c.Pages.Get(pid)
if err == sql.ErrNoRows {
return c.NotFound(w, r, basePage.Header)
@ -103,7 +102,6 @@ func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid s
if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user)
}
pname := r.PostFormValue("name")
if pname == "" {
return c.LocalError("No name was provided for this page", w, r, user)
@ -143,7 +141,6 @@ func PagesDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid
if err != nil {
return c.LocalError("Page ID needs to be an integer", w, r, user)
}
err = c.Pages.Delete(pid)
if err != nil {
return c.InternalError(err, w, r)

View File

@ -10,8 +10,8 @@ import (
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
p "github.com/Azareal/Gosora/common/phrases"
qgen "github.com/Azareal/Gosora/query_gen"
)
type ReplyStmts struct {
@ -353,7 +353,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid)
if err != nil {
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
}
reply, err := c.Rstore.Get(rid)
@ -410,7 +410,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid)
if err != nil {
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
}
reply, err := c.Rstore.Get(rid)
@ -443,7 +443,7 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
for _, said := range saids {
aid, err := strconv.Atoi(said)
if err != nil {
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
}
rerr := deleteAttachment(w, r, user, aid, true)
if rerr != nil {
@ -574,7 +574,6 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Use
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError {
js := (r.PostFormValue("js") == "1")
rid, err := strconv.Atoi(srid)
if err != nil {
return c.PreErrorJSQ("The provided Reply ID is not a valid number.", w, r, js)

View File

@ -281,8 +281,8 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
// Lock this to the forum being linked?
// Should we always put it in strictmode when it's linked from another forum? Well, the user might end up changing their mind on what forum they want to post in and it would be a hassle, if they had to switch pages, even if it is a single click for many (exc. mobile)
var strictmode bool
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strictmode)
var strict bool
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strict)
// TODO: Re-add support for plugin_guilds
var forumList []c.Forum
@ -306,7 +306,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
// TODO: plugin_superadmin needs to be able to override this loop. Skip flag on topic_create_pre_loop?
for _, ffid := range canSee {
// TODO: Surely, there's a better way of doing this. I've added it in for now to support plugin_guilds, but we really need to clean this up
if strictmode && ffid != fid {
if strict && ffid != fid {
continue
}
@ -339,10 +339,10 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return c.NoPermissions(w, r, user)
}
topicName := c.SanitiseSingleLine(r.PostFormValue("topic-name"))
tname := c.SanitiseSingleLine(r.PostFormValue("topic-name"))
content := c.PreparseMessage(r.PostFormValue("topic-content"))
// TODO: Fully parse the post and store it in the parsed column
tid, err := c.Topics.Create(fid, topicName, content, user.ID, user.LastIP)
tid, err := c.Topics.Create(fid, tname, content, user.ID, user.LastIP)
if err != nil {
switch err {
case c.ErrNoRows:
@ -362,8 +362,8 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return c.LocalError("Unable to load the topic", w, r, user)
}
if r.PostFormValue("has_poll") == "1" {
var maxPollOptions = 10
var pollInputItems = make(map[int]string)
maxPollOptions := 10
pollInputItems := make(map[int]string)
for key, values := range r.Form {
for _, value := range values {
if !strings.HasPrefix(key, "pollinputitem[") {
@ -394,7 +394,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
if len(pollInputItems) > 0 {
// Make sure the indices are sequential to avoid out of bounds issues
var seqPollInputItems = make(map[int]string)
seqPollInputItems := make(map[int]string)
for i := 0; i < len(pollInputItems); i++ {
seqPollInputItems[i] = pollInputItems[i]
}
@ -666,7 +666,7 @@ func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.R
return nil, nil, c.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
}
topic, err := c.Topics.Get(tid)
t, err := c.Topics.Get(tid)
if err == sql.ErrNoRows {
return nil, nil, c.PreError("The topic you tried to "+action+" doesn't exist.", w, r)
} else if err != nil {
@ -674,12 +674,11 @@ func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.R
}
// TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID)
lite, ferr := c.SimpleForumUserCheck(w, r, &user, t.ParentID)
if ferr != nil {
return nil, nil, ferr
}
return topic, lite, nil
return t, lite, nil
}
func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Request, lite *c.HeaderLite, topic *c.Topic, user c.User) c.RouteError {
@ -698,15 +697,15 @@ func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Re
return nil
}
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
topic, lite, rerr := topicActionPre(stid, "unpin", w, r, user)
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
t, lite, rerr := topicActionPre(stid, "unpin", w, r, u)
if rerr != nil {
return rerr
}
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
return c.NoPermissions(w, r, user)
if !u.Perms.ViewTopic || !u.Perms.PinTopic {
return c.NoPermissions(w, r, u)
}
return topicActionPost(topic.Unstick(), "unstick", w, r, lite, topic, user)
return topicActionPost(t.Unstick(), "unstick", w, r, lite, t, u)
}
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
@ -773,15 +772,15 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return nil
}
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError {
topic, lite, rerr := topicActionPre(stid, "unlock", w, r, user)
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError {
t, lite, rerr := topicActionPre(stid, "unlock", w, r, u)
if rerr != nil {
return rerr
}
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
return c.NoPermissions(w, r, user)
if !u.Perms.ViewTopic || !u.Perms.CloseTopic {
return c.NoPermissions(w, r, u)
}
return topicActionPost(topic.Unlock(), "unlock", w, r, lite, topic, user)
return topicActionPost(t.Unlock(), "unlock", w, r, lite, t, u)
}
// ! JS only route
@ -853,12 +852,12 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
return nil
}
func addTopicAction(action string, topic *c.Topic, user c.User) error {
err := c.ModLogs.Create(action, topic.ID, "topic", user.LastIP, user.ID)
func addTopicAction(action string, t *c.Topic, u c.User) error {
err := c.ModLogs.Create(action, t.ID, "topic", u.LastIP, u.ID)
if err != nil {
return err
}
return topic.CreateActionReply(action, user.LastIP, user.ID)
return t.CreateActionReply(action, u.LastIP, u.ID)
}
// TODO: Refactor this