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:
parent
cd89e836a1
commit
225a2cc8a1
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
14
main.go
|
@ -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")))
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue