0.1.0 tag, checkpoint release.

Upped the user cache capacity and topic cache capacity.
More resource management work. WIP.
Added Hyperdrive to the experimental folder. It doesn't really work right now, but I'd like to track it's progress.
Eliminated a line in global.js
This commit is contained in:
Azareal 2018-09-19 16:09:03 +10:00
parent cd89e836a1
commit 225a2cc8a1
7 changed files with 74 additions and 14 deletions

View File

@ -10,7 +10,9 @@ func NewNullUserCache() *NullUserCache {
} }
// nolint // nolint
func (mus *NullUserCache) DeallocOverflow() {} func (mus *NullUserCache) DeallocOverflow(evictPriority bool) (evicted int) {
return 0
}
func (mus *NullUserCache) Get(id int) (*User, error) { func (mus *NullUserCache) Get(id int) (*User, error) {
return nil, ErrNoRows return nil, ErrNoRows
} }

View File

@ -7,7 +7,7 @@ import (
// UserCache is an interface which spits out users from a fast cache rather than the database, whether from memory or from an application like Redis. Users may not be present in the cache but may be in the database // UserCache is an interface which spits out users from a fast cache rather than the database, whether from memory or from an application like Redis. Users may not be present in the cache but may be in the database
type UserCache interface { type UserCache interface {
DeallocOverflow() // May cause thread contention, looks for items to evict DeallocOverflow(evictPriority bool) (evicted int) // May cause thread contention, looks for items to evict
Get(id int) (*User, error) Get(id int) (*User, error)
GetUnsafe(id int) (*User, error) GetUnsafe(id int) (*User, error)
BulkGet(ids []int) (list []*User) BulkGet(ids []int) (list []*User)
@ -40,7 +40,7 @@ func NewMemoryUserCache(capacity int) *MemoryUserCache {
} }
// TODO: Avoid deallocating topic list users // TODO: Avoid deallocating topic list users
func (mus *MemoryUserCache) DeallocOverflow() { func (mus *MemoryUserCache) DeallocOverflow(evictPriority bool) (evicted int) {
var toEvict = make([]int, 10) var toEvict = make([]int, 10)
var evIndex = 0 var evIndex = 0
mus.RLock() mus.RLock()
@ -58,6 +58,25 @@ func (mus *MemoryUserCache) DeallocOverflow() {
} }
mus.RUnlock() mus.RUnlock()
// Clear some of the less active users now with a bit more aggressiveness
if evIndex == 0 && evictPriority {
toEvict = make([]int, 20)
mus.RLock()
for _, user := range mus.items {
if user.Score < 100 && !user.IsMod {
if EnableWebsockets && WsHub.HasUser(user.ID) {
continue
}
toEvict[evIndex] = user.ID
evIndex++
if evIndex == 20 {
break
}
}
}
mus.RUnlock()
}
// Remove zero IDs from the evictable list, so we don't waste precious cycles locked for those // Remove zero IDs from the evictable list, so we don't waste precious cycles locked for those
var lastZero = -1 var lastZero = -1
for i, uid := range toEvict { for i, uid := range toEvict {
@ -70,6 +89,7 @@ func (mus *MemoryUserCache) DeallocOverflow() {
} }
mus.BulkRemove(toEvict) mus.BulkRemove(toEvict)
return len(toEvict)
} }
// Get fetches a user by ID. Returns ErrNoRows if not present. // Get fetches a user by ID. Returns ErrNoRows if not present.

View File

@ -20,8 +20,8 @@
"MaxRequestSizeStr":"5MB", "MaxRequestSizeStr":"5MB",
"UserCache":"static", "UserCache":"static",
"TopicCache":"static", "TopicCache":"static",
"UserCacheCapacity":120, "UserCacheCapacity":150,
"TopicCacheCapacity":200, "TopicCacheCapacity":250,
"DefaultPath":"/topics/", "DefaultPath":"/topics/",
"DefaultGroup":3, "DefaultGroup":3,
"ActivationGroup":5, "ActivationGroup":5,

View File

@ -0,0 +1,34 @@
// Highly experimental plugin for caching rendered pages for guests
package main
import (
"sync/atomic"
"./common"
)
var hyperPageCache *HyperPageCache
func init() {
common.Plugins.Add(&common.Plugin{UName: "hyperdrive", Name: "Hyperdrive", Author: "Azareal", Init: initHyperdrive, Deactivate: deactivateHyperdrive})
}
func initHyperdrive() error {
hyperPageCache = newHyperPageCache()
common.Plugins["hyperdrive"].AddHook("somewhere", deactivateHyperdrive)
return nil
}
func deactivateHyperdrive() {
hyperPageCache = nil
}
type HyperPageCache struct {
topicList atomic.Value
}
func newHyperPageCache() *HyperPageCache {
pageCache := new(HyperPageCache)
pageCache.topicList.Store([]byte(""))
return pageCache
}

View File

@ -118,8 +118,8 @@ func main() {
"MaxRequestSizeStr":"5MB", "MaxRequestSizeStr":"5MB",
"UserCache":"static", "UserCache":"static",
"TopicCache":"static", "TopicCache":"static",
"UserCacheCapacity":120, "UserCacheCapacity":150,
"TopicCacheCapacity":200, "TopicCacheCapacity":250,
"DefaultPath":"/topics/", "DefaultPath":"/topics/",
"DefaultGroup":3, "DefaultGroup":3,
"ActivationGroup":5, "ActivationGroup":5,

14
main.go
View File

@ -29,7 +29,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
var version = common.Version{Major: 0, Minor: 1, Patch: 0, Tag: "dev"} var version = common.Version{Major: 0, Minor: 1, Patch: 0}
var router *GenRouter var router *GenRouter
var logWriter = io.MultiWriter(os.Stderr) var logWriter = io.MultiWriter(os.Stderr)
@ -373,13 +373,15 @@ func main() {
go tickLoop(thumbChan, halfSecondTicker, secondTicker, fifteenMinuteTicker, hourTicker) go tickLoop(thumbChan, halfSecondTicker, secondTicker, fifteenMinuteTicker, hourTicker)
// Resource Management Goroutine // Resource Management Goroutine
go func() { /*go func() {
ucache := common.Users.GetCache() ucache := common.Users.GetCache()
tcache := common.Topics.GetCache() tcache := common.Topics.GetCache()
if ucache == nil && tcache == nil { if ucache == nil && tcache == nil {
return return
} }
var lastEvictedCount int
var couldNotDealloc bool
for { for {
select { select {
case <-secondTicker.C: case <-secondTicker.C:
@ -387,13 +389,17 @@ func main() {
if ucache != nil { if ucache != nil {
ucap := ucache.GetCapacity() ucap := ucache.GetCapacity()
if ucache.Length() <= ucap || common.Users.GlobalCount() <= ucap { if ucache.Length() <= ucap || common.Users.GlobalCount() <= ucap {
countNotDealloc = false
continue continue
} }
//ucache.DeallocOverflow() lastEvictedCount = ucache.DeallocOverflow(countNotDealloc)
countNotDealloc = (lastEvictedCount == 0)
} else {
countNotDealloc = false
} }
} }
} }
}() }()*/
log.Print("Initialising the router") log.Print("Initialising the router")
router, err = NewGenRouter(http.FileServer(http.Dir("./uploads"))) router, err = NewGenRouter(http.FileServer(http.Dir("./uploads")))

View File

@ -121,13 +121,11 @@ function loadAlerts(menuAlerts) {
updateAlertList(menuAlerts) updateAlertList(menuAlerts)
}, },
error: (magic,theStatus,error) => { error: (magic,theStatus,error) => {
let errtxt let errtxt = "Unable to get the alerts";
try { try {
var data = JSON.parse(magic.responseText); var data = JSON.parse(magic.responseText);
if("errmsg" in data) errtxt = data.errmsg; if("errmsg" in data) errtxt = data.errmsg;
else errtxt = "Unable to get the alerts";
} catch(err) { } catch(err) {
errtxt = "Unable to get the alerts";
console.log(magic.responseText); console.log(magic.responseText);
console.log(err); console.log(err);
} }