From 8a1c770079c10c74fd048fb7153df6b8e117af22 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 20 Feb 2026 15:44:06 -0700 Subject: [PATCH] added more tuning knobs, particularly in cache sizes --- config/config.go | 22 ++++++++++++++++++++++ config/default.yaml | 11 +++++++++++ database/base.go | 24 ++++++++++++++---------- database/community.go | 11 ++++++----- database/conference.go | 9 +++++---- database/contactinfo.go | 7 ++++--- database/services.go | 11 ++++++++--- database/user.go | 9 +++++---- main.go | 1 + ui/menus.go | 15 ++++++++++----- 10 files changed, 86 insertions(+), 34 deletions(-) diff --git a/config/config.go b/config/config.go index d49025b..66075d9 100644 --- a/config/config.go +++ b/config/config.go @@ -108,6 +108,18 @@ type AmConfig struct { IPBans int `yaml:"ipBans"` WorkerTasks int `yaml:"workerTasks"` } `yaml:"queues"` + Caches struct { + Communities int `yaml:"communities"` + CommunityProps int `yaml:"communityProps"` + Conferences int `yaml:"conferences"` + ConferenceProps int `yaml:"conferenceProps"` + ContactInfo int `yaml:"contactInfo"` + Members int `yaml:"members"` + Menus int `yaml:"menus"` + Services int `yaml:"services"` + Users int `yaml:"users"` + UserProps int `yaml:"userProps"` + } `yaml:"caches"` } `yaml:"tuning"` } @@ -228,6 +240,16 @@ func overlayConfig(dest *AmConfig, loaded *AmConfig, defaults *AmConfig) { dest.Tuning.Queues.EmailSend = overlayInt(loaded.Tuning.Queues.EmailSend, defaults.Tuning.Queues.EmailSend) dest.Tuning.Queues.IPBans = overlayInt(loaded.Tuning.Queues.IPBans, defaults.Tuning.Queues.IPBans) dest.Tuning.Queues.WorkerTasks = overlayInt(loaded.Tuning.Queues.WorkerTasks, defaults.Tuning.Queues.WorkerTasks) + dest.Tuning.Caches.Communities = overlayInt(loaded.Tuning.Caches.Communities, defaults.Tuning.Caches.Communities) + dest.Tuning.Caches.CommunityProps = overlayInt(loaded.Tuning.Caches.CommunityProps, defaults.Tuning.Caches.CommunityProps) + dest.Tuning.Caches.Conferences = overlayInt(loaded.Tuning.Caches.Conferences, defaults.Tuning.Caches.Conferences) + dest.Tuning.Caches.ConferenceProps = overlayInt(loaded.Tuning.Caches.ConferenceProps, defaults.Tuning.Caches.ConferenceProps) + dest.Tuning.Caches.ContactInfo = overlayInt(loaded.Tuning.Caches.ContactInfo, defaults.Tuning.Caches.ContactInfo) + dest.Tuning.Caches.Members = overlayInt(loaded.Tuning.Caches.Members, defaults.Tuning.Caches.Members) + dest.Tuning.Caches.Menus = overlayInt(loaded.Tuning.Caches.Menus, defaults.Tuning.Caches.Menus) + dest.Tuning.Caches.Services = overlayInt(loaded.Tuning.Caches.Services, defaults.Tuning.Caches.Services) + dest.Tuning.Caches.Users = overlayInt(loaded.Tuning.Caches.Users, defaults.Tuning.Caches.Users) + dest.Tuning.Caches.UserProps = overlayInt(loaded.Tuning.Caches.UserProps, defaults.Tuning.Caches.UserProps) } // parseDataSize converts the data size in bytes, kilobytes, megabytes, or gigabytes to a number value. diff --git a/config/default.yaml b/config/default.yaml index 59f5230..6a2e346 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -61,3 +61,14 @@ tuning: emailSend: 16 ipBans: 32 workerTasks: 128 + caches: + communities: 50 + communityProps: 100 + conferences: 100 + conferenceProps: 100 + contactInfo: 100 + members: 250 + menus: 100 + services: 50 + users: 100 + userProps: 100 \ No newline at end of file diff --git a/database/base.go b/database/base.go index 373743e..5258ed8 100644 --- a/database/base.go +++ b/database/base.go @@ -10,30 +10,34 @@ package database import ( + "slices" + "git.erbosoft.com/amy/amsterdam/config" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) -// amdb is the reference to the Amsterdam database. Returns a function to close it down. +// amdb is the reference to the Amsterdam database. var amdb *sqlx.DB // SetupDb sets up the database and associated items. func SetupDb() (func(), error) { - var fn1 func() = nil - var fn2 func() = nil + exitfns := make([]func(), 0, 2) db, err := sqlx.Open(config.GlobalConfig.Database.Driver, config.GlobalConfig.Database.Dsn) if err == nil { amdb = db - fn1 = setupAuditWriter() - fn2 = setupIPBanSweep() + setupUserCache() + setupContactsCache() + setupCommunityCache() + setupServicesCache() + setupConferenceCache() + exitfns = append(exitfns, setupAuditWriter()) + exitfns = append(exitfns, setupIPBanSweep()) } return func() { - if fn2 != nil { - fn2() - } - if fn1 != nil { - fn1() + slices.Reverse(exitfns) + for _, f := range exitfns { + f() } amdb.Close() }, err diff --git a/database/community.go b/database/community.go index ad60764..9dc0c8e 100644 --- a/database/community.go +++ b/database/community.go @@ -20,6 +20,7 @@ import ( "sync" "time" + "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/util" lru "github.com/hashicorp/golang-lru" "github.com/jmoiron/sqlx" @@ -130,18 +131,18 @@ func stuffMembership(cid int32, uid int32, member bool, locked bool, level uint1 memberMutex.Unlock() } -// init initializes the caches. -func init() { +// setupCommunityCache initializes the caches. +func setupCommunityCache() { var err error - communityCache, err = lru.New2Q(50) + communityCache, err = lru.New2Q(config.GlobalConfig.Tuning.Caches.Communities) if err != nil { panic(err) } - memberCache, err = lru.New(250) + memberCache, err = lru.New(config.GlobalConfig.Tuning.Caches.Members) if err != nil { panic(err) } - communityPropCache, err = lru.New(100) + communityPropCache, err = lru.New(config.GlobalConfig.Tuning.Caches.CommunityProps) if err != nil { panic(err) } diff --git a/database/conference.go b/database/conference.go index d15d917..14c2c32 100644 --- a/database/conference.go +++ b/database/conference.go @@ -19,6 +19,7 @@ import ( "sync" "time" + "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/util" lru "github.com/hashicorp/golang-lru" "github.com/jmoiron/sqlx" @@ -115,14 +116,14 @@ var conferencePropCache *lru.Cache = nil // getConferencePropMutex is a mutex on AmGetConferenceProperty. var getConferencePropMutex sync.Mutex -// init initializes the conference cache. -func init() { +// setupConferenceCache initializes the conference cache. +func setupConferenceCache() { var err error - conferenceCache, err = lru.New2Q(100) + conferenceCache, err = lru.New2Q(config.GlobalConfig.Tuning.Caches.Conferences) if err != nil { panic(err) } - conferencePropCache, err = lru.New(100) + conferencePropCache, err = lru.New(config.GlobalConfig.Tuning.Caches.ConferenceProps) if err != nil { panic(err) } diff --git a/database/contactinfo.go b/database/contactinfo.go index 01e765b..0f0fa63 100644 --- a/database/contactinfo.go +++ b/database/contactinfo.go @@ -18,6 +18,7 @@ import ( "sync" "time" + "git.erbosoft.com/amy/amsterdam/config" lru "github.com/hashicorp/golang-lru" ) @@ -236,10 +237,10 @@ var contactCache *lru.TwoQueueCache = nil // getContactMutex is a mutex on AmGetContactInfo. var getContactMutex sync.Mutex -// init initializes the contact info cache. -func init() { +// setupContactsCache initializes the contact info cache. +func setupContactsCache() { var err error - contactCache, err = lru.New2Q(100) + contactCache, err = lru.New2Q(config.GlobalConfig.Tuning.Caches.ContactInfo) if err != nil { panic(err) } diff --git a/database/services.go b/database/services.go index 240e153..cf12422 100644 --- a/database/services.go +++ b/database/services.go @@ -16,6 +16,7 @@ import ( "slices" "sync" + "git.erbosoft.com/amy/amsterdam/config" lru "github.com/hashicorp/golang-lru" "github.com/jmoiron/sqlx" "gopkg.in/yaml.v3" @@ -91,8 +92,7 @@ var servicesCacheMutex sync.Mutex // init loads the service configuration and builds all the internal indexes. func init() { - var err error - if err = yaml.Unmarshal(initServiceData, &serviceRoot); err != nil { + if err := yaml.Unmarshal(initServiceData, &serviceRoot); err != nil { panic(err) // can't happen } serviceRoot.byName = make(map[string]*ServiceDomain) @@ -118,7 +118,12 @@ func init() { dom.byId["SysAdmin"].vtable = &empty dom.byId["Conference"].vtable = &empty // TODO dom.byId["Members"].vtable = &empty - servicesCache, err = lru.New2Q(50) +} + +// setupServicesCache sets up the services cache. +func setupServicesCache() { + var err error + servicesCache, err = lru.New2Q(config.GlobalConfig.Tuning.Caches.Services) if err != nil { panic(err) } diff --git a/database/user.go b/database/user.go index 25c0c21..e99e2ee 100644 --- a/database/user.go +++ b/database/user.go @@ -22,6 +22,7 @@ import ( "sync" "time" + "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/util" lru "github.com/hashicorp/golang-lru" "github.com/jmoiron/sqlx" @@ -188,14 +189,14 @@ var getUserPropMutex sync.Mutex // anonUid is the UID of the "anonymous" user. var anonUid int32 = -1 -// init initializes the caches. -func init() { +// setupUserCache initializes the caches. +func setupUserCache() { var err error - userCache, err = lru.New2Q(100) + userCache, err = lru.New2Q(config.GlobalConfig.Tuning.Caches.Users) if err != nil { panic(err) } - userPropCache, err = lru.New(100) + userPropCache, err = lru.New(config.GlobalConfig.Tuning.Caches.UserProps) if err != nil { panic(err) } diff --git a/main.go b/main.go index 52f1626..1deb790 100644 --- a/main.go +++ b/main.go @@ -182,6 +182,7 @@ func main() { defer closer() htmlcheck.SetupDicts() ui.SetupTemplates() + ui.SetupMenuCache() closer = ui.SetupAmSessionManager() defer closer() closer = ui.SetupAmContext() diff --git a/ui/menus.go b/ui/menus.go index c419eaa..54697b7 100644 --- a/ui/menus.go +++ b/ui/menus.go @@ -18,6 +18,7 @@ import ( "strings" "sync" + "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/util" lru "github.com/hashicorp/golang-lru" @@ -142,11 +143,7 @@ var menuCacheMutex sync.Mutex // init loads the menu definitions. func init() { - var err error - if menuCache, err = lru.New(100); err != nil { - panic(err) - } - if err = yaml.Unmarshal(initMenuData, &menuDefinitions); err != nil { + if err := yaml.Unmarshal(initMenuData, &menuDefinitions); err != nil { panic(err) // can't happen } menuDefinitions.table = make(map[string]*MenuDefinition) @@ -159,6 +156,14 @@ func init() { } } +// SetupMenuCache sets up the menu cache. +func SetupMenuCache() { + var err error + if menuCache, err = lru.New(config.GlobalConfig.Tuning.Caches.Menus); err != nil { + panic(err) + } +} + // AmMenu returns a menu definition. func AmMenu(name string) *MenuDefinition { return menuDefinitions.table[name]