cache roles

This commit is contained in:
Dot-Rar 2020-03-23 23:30:48 +00:00
parent 469c8e0883
commit 9e5d919e6e
4 changed files with 59 additions and 64 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/apex/log"
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
"strconv"
"time"
)
@ -82,6 +83,10 @@ func CallbackHandler(ctx *gin.Context) {
ctx.Redirect(302, config.Conf.Server.BaseUrl)
userId, err := strconv.ParseInt(currentUser.Id, 10, 64); if err != nil { // ???
return
}
// Cache guilds because Discord takes like 2 whole seconds to return then
go func() {
var guilds []objects.Guild
@ -93,6 +98,12 @@ func CallbackHandler(ctx *gin.Context) {
for _, guild := range guilds {
go cache.Client.StoreGuild(guild)
// cache roles
guildId, err := strconv.ParseInt(guild.Id, 10, 64); if err != nil {
continue
}
go cacheRoles(store, guildId, userId)
}
marshalled, err := json.Marshal(guilds)
@ -106,21 +117,16 @@ func CallbackHandler(ctx *gin.Context) {
}
func cacheRoles(store sessions.Session, guildId, userId int64) {
rolesChan := make(chan *[]int64, 0)
go utils.GetRolesRest(store, guildId, userId, rolesChan)
roles := <-rolesChan
roles := utils.GetRolesRest(store, guildId, userId)
if roles == nil {
return
}
memberIdChan := make(chan *int)
go table.GetMemberId(guildId, userId, memberIdChan)
memberId := <-memberIdChan
// Delete old roles
table.DeleteRoles(guildId, userId)
if memberId == nil {
return
for _, role := range *roles {
table.CacheRole(guildId, userId, role)
}
}

View File

@ -1,38 +0,0 @@
package table
import (
"github.com/TicketsBot/GoPanel/database"
"github.com/apex/log"
)
// Use an intermediary table to prevent a many-to-many relationship
type MemberId struct {
MemberId int `gorm:"column:MEMBERID;primary_key;auto_increment"`
GuildId int64 `gorm:"column:GUILDID"`
UserId int64 `gorm:"column:USERID"`
}
func (MemberId) TableName() string {
return "cache_memberids"
}
func GetMemberId(guildId, userId int64, ch chan *int) {
var row MemberId
database.Database.Where(&MemberId{GuildId: guildId, UserId: userId}).Take(&row)
if row.MemberId == 0 {
row = MemberId{
GuildId: guildId,
UserId: userId,
}
if db := database.Database.Create(row).Scan(&row); db.Error != nil {
log.Error(db.Error.Error())
ch <- nil
return
}
ch <- &row.MemberId
} else {
ch <- &row.MemberId
}
}

View File

@ -1,11 +1,44 @@
package table
// Use an intermediary table to prevent a many-to-many relationship
type RoleCache struct {
MemberId int `gorm:"column:MEMBERID;primary_key"`
RoleId int64 `gorm:"column:ROLEID"`
import "github.com/TicketsBot/TicketsGo/database"
type CachedRole struct {
AssociationId int `gorm:"column:ASSOCIATIONID;primary_key;auto_increment"`
GuildId int64 `gorm:"column:GUILDID"`
UserId int64 `gorm:"column:USERID"`
RoleId int64 `gorm:"column:ROLEID"`
}
func (RoleCache) TableName() string {
func (CachedRole) TableName() string {
return "cache_roles"
}
func DeleteRoles(guildId, userId int64) {
database.Db.Where(CachedRole{
GuildId: guildId,
UserId: userId,
}).Delete(CachedRole{})
}
// TODO: Cache invalidation
func CacheRole(guildId, userId, roleId int64) {
database.Db.Create(&CachedRole{
GuildId: guildId,
UserId: userId,
RoleId: roleId,
})
}
func GetCachedRoles(guildId, userId int64, res chan []int64) {
var rows []CachedRole
database.Db.Where(&CachedRole{
GuildId: guildId,
UserId: userId,
}).Find(&rows)
roles := make([]int64, 0)
for _, row := range rows {
roles = append(roles, row.RoleId)
}
res <- roles
}

View File

@ -1,7 +1,6 @@
package utils
import (
"fmt"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
"github.com/TicketsBot/GoPanel/utils/discord/endpoints/guild"
@ -31,7 +30,9 @@ func IsAdmin(store sessions.Session, guild objects.Guild, guildId, userId int64,
res <- true
}
userRoles := GetRoles(store, guildId, userId)
userRolesChan := make(chan []int64)
go table.GetCachedRoles(guildId, userId, userRolesChan)
userRoles := <-userRolesChan
adminRolesChan := make(chan []int64)
go table.GetAdminRoles(strconv.Itoa(int(guildId)), adminRolesChan)
@ -54,12 +55,7 @@ func IsAdmin(store sessions.Session, guild objects.Guild, guildId, userId int64,
res <- false
}
func GetRoles(store sessions.Session, guildId, userId int64) []int64 {
key := fmt.Sprintf("%d-%d", guildId, userId)
if cached, ok := roleCache.Get(key); ok {
return cached.([]int64)
}
func GetRolesRest(store sessions.Session, guildId, userId int64) *[]int64 {
var member objects.Member
endpoint := guild.GetGuildMember(int(guildId), int(userId))
@ -67,7 +63,5 @@ func GetRoles(store sessions.Session, guildId, userId int64) []int64 {
return nil
}
roleCache.Set(key, &member.Roles, time.Minute)
return member.Roles
return &member.Roles
}