🚑 Fix write map panic with mutex
This commit is contained in:
parent
727b259ca7
commit
c7ba566c48
@ -2,10 +2,12 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
"git.solsynth.dev/hydrogen/passport/pkg/services"
|
||||||
"github.com/gofiber/contrib/websocket"
|
"github.com/gofiber/contrib/websocket"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,6 +16,7 @@ func listenWebsocket(c *websocket.Conn) {
|
|||||||
|
|
||||||
// Push connection
|
// Push connection
|
||||||
services.ClientRegister(user, c)
|
services.ClientRegister(user, c)
|
||||||
|
log.Debug().Uint("user", user.ID).Msg("New websocket connection established...")
|
||||||
|
|
||||||
// Event loop
|
// Event loop
|
||||||
var task models.UnifiedCommand
|
var task models.UnifiedCommand
|
||||||
@ -76,4 +79,5 @@ func listenWebsocket(c *websocket.Conn) {
|
|||||||
|
|
||||||
// Pop connection
|
// Pop connection
|
||||||
services.ClientUnregister(user, c)
|
services.ClientUnregister(user, c)
|
||||||
|
log.Debug().Uint("user", user.ID).Msg("A websocket connection disconnected...")
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,20 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
jsoniter "github.com/json-iterator/go"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var authContextCache = make(map[string]models.AuthContext)
|
var (
|
||||||
|
authContextMutex sync.Mutex
|
||||||
|
authContextCache = make(map[string]models.AuthContext)
|
||||||
|
)
|
||||||
|
|
||||||
func Authenticate(access, refresh string, depth int) (ctx models.AuthContext, perms map[string]any, newAccess, newRefresh string, err error) {
|
func Authenticate(access, refresh string, depth int) (ctx models.AuthContext, perms map[string]any, newAccess, newRefresh string, err error) {
|
||||||
var claims PayloadClaims
|
var claims PayloadClaims
|
||||||
@ -50,7 +55,9 @@ func GetAuthContext(jti string) (models.AuthContext, error) {
|
|||||||
if val, ok := authContextCache[jti]; ok {
|
if val, ok := authContextCache[jti]; ok {
|
||||||
ctx = val
|
ctx = val
|
||||||
ctx.LastUsedAt = time.Now()
|
ctx.LastUsedAt = time.Now()
|
||||||
|
authContextMutex.Lock()
|
||||||
authContextCache[jti] = ctx
|
authContextCache[jti] = ctx
|
||||||
|
authContextMutex.Unlock()
|
||||||
log.Debug().Str("jti", jti).Msg("Used an auth context cache")
|
log.Debug().Str("jti", jti).Msg("Used an auth context cache")
|
||||||
} else {
|
} else {
|
||||||
ctx, err = CacheAuthContext(jti)
|
ctx, err = CacheAuthContext(jti)
|
||||||
@ -83,7 +90,9 @@ func CacheAuthContext(jti string) (models.AuthContext, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put the data into memory for cache
|
// Put the data into memory for cache
|
||||||
|
authContextMutex.Lock()
|
||||||
authContextCache[jti] = ctx
|
authContextCache[jti] = ctx
|
||||||
|
authContextMutex.Unlock()
|
||||||
|
|
||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
@ -97,7 +106,9 @@ func RecycleAuthContext() {
|
|||||||
for key, val := range authContextCache {
|
for key, val := range authContextCache {
|
||||||
if val.LastUsedAt.Add(60*time.Second).Unix() < time.Now().Unix() {
|
if val.LastUsedAt.Add(60*time.Second).Unix() < time.Now().Unix() {
|
||||||
affected++
|
affected++
|
||||||
|
authContextMutex.Lock()
|
||||||
delete(authContextCache, key)
|
delete(authContextCache, key)
|
||||||
|
authContextMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debug().Int("affected", affected).Msg("Recycled auth context...")
|
log.Debug().Int("affected", affected).Msg("Recycled auth context...")
|
||||||
@ -106,7 +117,9 @@ func RecycleAuthContext() {
|
|||||||
func InvalidAuthCacheWithUser(userId uint) {
|
func InvalidAuthCacheWithUser(userId uint) {
|
||||||
for key, val := range authContextCache {
|
for key, val := range authContextCache {
|
||||||
if val.Account.ID == userId {
|
if val.Account.ID == userId {
|
||||||
|
authContextMutex.Lock()
|
||||||
delete(authContextCache, key)
|
delete(authContextCache, key)
|
||||||
|
authContextMutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,31 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
"git.solsynth.dev/hydrogen/passport/pkg/models"
|
||||||
"github.com/gofiber/contrib/websocket"
|
"github.com/gofiber/contrib/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
var wsConn = make(map[uint]map[*websocket.Conn]bool)
|
var (
|
||||||
|
wsMutex sync.Mutex
|
||||||
|
wsConn = make(map[uint]map[*websocket.Conn]bool)
|
||||||
|
)
|
||||||
|
|
||||||
func ClientRegister(user models.Account, conn *websocket.Conn) {
|
func ClientRegister(user models.Account, conn *websocket.Conn) {
|
||||||
|
wsMutex.Lock()
|
||||||
if wsConn[user.ID] == nil {
|
if wsConn[user.ID] == nil {
|
||||||
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
||||||
}
|
}
|
||||||
wsConn[user.ID][conn] = true
|
wsConn[user.ID][conn] = true
|
||||||
|
wsMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClientUnregister(user models.Account, conn *websocket.Conn) {
|
func ClientUnregister(user models.Account, conn *websocket.Conn) {
|
||||||
|
wsMutex.Lock()
|
||||||
if wsConn[user.ID] == nil {
|
if wsConn[user.ID] == nil {
|
||||||
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
||||||
}
|
}
|
||||||
delete(wsConn[user.ID], conn)
|
delete(wsConn[user.ID], conn)
|
||||||
|
wsMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ access_token_duration = 300
|
|||||||
refresh_token_duration = 2592000
|
refresh_token_duration = 2592000
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
dsn = "host=localhost dbname=hy_passport port=5432 sslmode=disable"
|
dsn = "host=localhost user=postgres password=password dbname=hy_passport port=5432 sslmode=disable"
|
||||||
prefix = "passport_"
|
prefix = "passport_"
|
||||||
|
|
||||||
[permissions.default]
|
[permissions.default]
|
||||||
|
Loading…
Reference in New Issue
Block a user