refactor Gateway out

trunk
vilmibm 2022-12-23 21:31:08 -08:00
parent 9824fecaa2
commit d006c992ec
2 changed files with 41 additions and 56 deletions

View File

@ -71,10 +71,12 @@ func _main() (err error) {
type gameWorldServer struct {
proto.UnimplementedGameWorldServer
db db.DB
mu sync.Mutex // for msgRouter
msgRouter map[string]func(*proto.ClientMessage) error
Gateway *witch.Gateway
db db.DB
msgRouterMutex sync.Mutex
msgRouter map[string]func(*proto.ClientMessage) error
Gateway *witch.Gateway
scripts map[int]*witch.ScriptContext
scriptsMutex sync.RWMutex
}
func newServer() (*gameWorldServer, error) {
@ -93,15 +95,39 @@ func newServer() (*gameWorldServer, error) {
}
s := &gameWorldServer{
msgRouter: make(map[string]func(*proto.ClientMessage) error),
db: db,
msgRouter: make(map[string]func(*proto.ClientMessage) error),
db: db,
scripts: make(map[int]*witch.ScriptContext),
scriptsMutex: sync.RWMutex{},
}
gw := witch.NewGateway(s.HandleCmd)
s.Gateway = gw
return s, nil
}
func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Object) error {
/*
So right here is a problem: we are definitely making >1 LuaState per
goroutine. Top priority before anything else is getting a goroutine made
for the script contexts
*/
s.scriptsMutex.RLock()
sc, ok := s.scripts[target.ID]
s.scriptsMutex.RUnlock()
if !ok || sc.NeedsRefresh(target) {
sc, err := witch.NewScriptContext(target)
if err != nil {
return err
}
s.scriptsMutex.Lock()
s.scripts[target.ID] = sc
s.scriptsMutex.Unlock()
}
return sc.Handle(verb, rest, sender, target)
}
func (s *gameWorldServer) HandleCmd(verb, rest string, sender *db.Object) {
// TODO
}
@ -213,9 +239,9 @@ func (s *gameWorldServer) Ping(ctx context.Context, _ *proto.SessionInfo) (*prot
}
func (s *gameWorldServer) Messages(si *proto.SessionInfo, stream proto.GameWorld_MessagesServer) error {
s.mu.Lock()
s.msgRouterMutex.Lock()
s.msgRouter[si.SessionID] = stream.Send
s.mu.Unlock()
s.msgRouterMutex.Unlock()
// TODO this is clearly bad but it works. I should refactor this so that messages are received on a channel.
for {

View File

@ -1,8 +1,6 @@
package witch
import (
"sync"
"github.com/vilmibm/hermeticum/server/db"
lua "github.com/yuin/gopher-lua"
)
@ -15,14 +13,14 @@ import (
*/
type scriptContext struct {
type ScriptContext struct {
script string
l *lua.LState
incoming chan string
// TODO whatever is needed to support calling a Go API
}
func (sc *scriptContext) NeedsRefresh(obj db.Object) bool {
func (sc *ScriptContext) NeedsRefresh(obj db.Object) bool {
return sc.script != obj.Script
}
@ -62,7 +60,7 @@ end)
// - do i inject from Go or prepend some Lua code?
// TODO figure out how the Lua code can affect Go and thus the database
func newScriptContext(obj db.Object) (*scriptContext, error) {
func NewScriptContext(obj db.Object) (*ScriptContext, error) {
l := lua.NewState()
l.SetGlobal("has", l.NewFunction(hasWrapper(obj)))
@ -73,49 +71,10 @@ func newScriptContext(obj db.Object) (*scriptContext, error) {
return nil, err
}
return &scriptContext{}, nil
return &ScriptContext{}, nil
}
func (sc *scriptContext) Handle(verb, rest string, sender, target *db.Object) error {
func (sc *ScriptContext) Handle(verb, rest string, sender, target db.Object) error {
// TODO call _handle function from the Lstate
return nil
}
type Gateway struct {
// maps game object IDs to script contexts
m map[int]*scriptContext
mu sync.RWMutex
cb func(string, string, *db.Object)
}
func NewGateway(cb func(string, string, *db.Object)) *Gateway {
return &Gateway{
m: map[int]*scriptContext{},
mu: sync.RWMutex{},
// TODO use cb from scriptContext
cb: cb,
}
}
func (g *Gateway) VerbHandler(verb, rest string, sender, target db.Object) error {
var sc *scriptContext
g.mu.RLock()
sc, ok := g.m[target.ID]
g.mu.RUnlock()
if !ok || sc.NeedsRefresh(target) {
sc, err := newScriptContext(target)
if err != nil {
return err
}
g.mu.Lock()
g.m[target.ID] = sc
g.mu.Unlock()
}
sc.Handle(verb, rest, &sender, &target)
return nil
}