fix a lot of bugs, adding detailed log output

This commit is contained in:
MahnoKropotkinvich 2025-01-03 22:00:10 +08:00
parent 3ff5df091a
commit e33d213789
6 changed files with 98 additions and 62 deletions

View File

@ -1,8 +1,9 @@
package main package main
import ( import (
"gopkg.in/yaml.v2"
"os" "os"
"gopkg.in/yaml.v2"
) )
type Config struct { type Config struct {
@ -10,10 +11,20 @@ type Config struct {
StartCommand string `yaml:"start_command"` StartCommand string `yaml:"start_command"`
Port string `yaml:"port"` Port string `yaml:"port"`
ConnectTimeout int `yaml:"connect_timeout"` //seconds ConnectTimeout int `yaml:"connect_timeout"` //seconds
MCPort string `yaml:"mc_port"`
}
var defaultConfig = Config{
MCPort: "25565",
ConnectTimeout: 10,
Port: "4567",
Timeout: 1,
} }
// this is a global constant since it's shared // this is a global constant since it's shared
var config Config var config = Config{}
const DEFAULT_VALUE_FMT_STR = "%s not found, default to %v"
func LoadConfig(filePath string) error { func LoadConfig(filePath string) error {
data, err := os.ReadFile(filePath) data, err := os.ReadFile(filePath)
@ -26,5 +37,21 @@ func LoadConfig(filePath string) error {
return err return err
} }
GetLogger().Info("Configuration loaded successfully") GetLogger().Info("Configuration loaded successfully")
if config.MCPort == "" {
GetLogger().Warnf(DEFAULT_VALUE_FMT_STR, "MCPort", defaultConfig.MCPort)
config.MCPort = defaultConfig.MCPort
}
if config.ConnectTimeout == 0 {
GetLogger().Warnf(DEFAULT_VALUE_FMT_STR, "ConnectTimeout", defaultConfig.ConnectTimeout)
config.ConnectTimeout = defaultConfig.ConnectTimeout
}
if config.Port == "" {
GetLogger().Warnf(DEFAULT_VALUE_FMT_STR, "Port", defaultConfig.Port)
config.Port = defaultConfig.Port
}
if config.Timeout == 0 {
GetLogger().Warnf(DEFAULT_VALUE_FMT_STR, "Timeout", defaultConfig.Timeout)
config.Timeout = defaultConfig.Timeout
}
return nil return nil
} }

12
conn.go
View File

@ -40,7 +40,7 @@ func handleConn(clientOriginal net.Conn) {
defer close(queryChan) defer close(queryChan)
QueryChanChan <- queryChan QueryChanChan <- queryChan
proceed := func() { proceed := func() {
server, err := net.Dial("tcp", "127.0.0.1:25565") server, err := net.Dial("tcp", "127.0.0.1:"+config.MCPort)
if err != nil { if err != nil {
GetLogger().Errorf("Failed to connect to MC server: %v", err) GetLogger().Errorf("Failed to connect to MC server: %v", err)
return return
@ -66,21 +66,23 @@ func handleConn(clientOriginal net.Conn) {
wg.Wait() wg.Wait()
GetLogger().Infof("Connection from %s closed", clientOriginal.RemoteAddr()) GetLogger().Infof("Connection from %s closed", clientOriginal.RemoteAddr())
} }
CntChan <- INCREASE
defer func() { CntChan <- DECREASE }()
queryChan <- STOPPED queryChan <- STOPPED
st, _ := <-queryChan st, _ := <-queryChan
switch st { switch st {
case RUNNING: case RUNNING:
CntChan <- INCREASE
defer func() { CntChan <- DECREASE }()
proceed() proceed()
case STOPPED, WAITING: case STOPPED, WAITING:
// client.Write([]byte("Server not ready!")) // client.Write([]byte("Server not ready!"))
GetLogger().Infof("Connection queued, server currently at %s state", stateToStr[state]) GetLogger().Infof("Connection queued, server currently at %s state", stateToStr[state])
CntChan <- INCREASE
defer func() { CntChan <- DECREASE }()
curChan := make(chan MCState) curChan := make(chan MCState)
defer close(curChan) defer close(curChan)
clientSignalChan.Add(curChan) clientSignalChan.Add(curChan)
state, _ := <-curChan st, _ := <-curChan
if state == RUNNING { if st == RUNNING {
proceed() proceed()
} else { } else {
client.Write([]byte("You are too late, server dying!")) client.Write([]byte("You are too late, server dying!"))

View File

@ -20,6 +20,7 @@ func Booting() {
proc = exec.Command(arg[0], arg[1:]...) proc = exec.Command(arg[0], arg[1:]...)
proc.Stdout = os.Stdout proc.Stdout = os.Stdout
proc.Stderr = os.Stderr proc.Stderr = os.Stderr
proc.Stdin = os.Stdin
proc.Start() proc.Start()
DaemonChanRX <- struct{}{} DaemonChanRX <- struct{}{}
GetLogger().Info("enter RUNNING state") GetLogger().Info("enter RUNNING state")

99
ds.go
View File

@ -115,7 +115,7 @@ func NewDynamicMultiChan[T constraints.Ordered](reply bool, m int) *DynamicMulti
modify: make(chan modify_t[T]), modify: make(chan modify_t[T]),
} }
mode := m mode := m
reload := make(chan struct{}) reload := make([]chan struct{}, 0)
used := make(map[int]bool) used := make(map[int]bool)
unused := make(map[int]bool) unused := make(map[int]bool)
// delta := -1 // delta := -1
@ -129,8 +129,8 @@ func NewDynamicMultiChan[T constraints.Ordered](reply bool, m int) *DynamicMulti
op := modification.op op := modification.op
id := modification.id id := modification.id
ch := modification.ch ch := modification.ch
for range viewCnt { for _, v := range reload {
reload <- struct{}{} v <- struct{}{}
} }
switch op { switch op {
case ADD: case ADD:
@ -167,64 +167,67 @@ func NewDynamicMultiChan[T constraints.Ordered](reply bool, m int) *DynamicMulti
} }
//deleted <- struct{}{} // <-reloadTX //extra communication //deleted <- struct{}{} // <-reloadTX //extra communication
} }
for range viewCnt { for _, v := range reload {
reload <- struct{}{} v <- struct{}{}
} }
} }
}() }()
go func() { {
chanId := viewCnt
viewCnt++ viewCnt++
reload = append(reload, make(chan struct{}))
selectCases[0] = reflect.SelectCase{ selectCases[0] = reflect.SelectCase{
Dir: reflect.SelectRecv, Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(reload), Chan: reflect.ValueOf(reload[chanId]),
} }
prevId := -1 prevId := -1
for {
id, recv, ok := reflect.Select(selectCases)
if prevId != -1 {
selectCases[prevId].Dir = reflect.SelectRecv
selectCases[prevId].Send = reflect.Value{}
prevId = -1
}
if !ok {
// ret.used.Push(id)
//
// delete(used, id)
ret.modify <- modify_t[T]{DELETE, id - 1, nil}
<-reload
// reloadRX <- struct{}{} //I'm currently not dealing with other chan
<-reload //waiting for you finished
// reloadRX <- struct{}{} //I've read all deltas, you can release them
continue
}
if mode == 1 && id != 0 {
ret.RX <- To[T](recv) // possible for below to send to Chan?
if ret.reply {
msg, _ := <-ret.TX
selectCases[id].Dir = reflect.SelectSend
selectCases[id].Send = reflect.ValueOf(msg)
prevId = id
}
} else if id == 0 {
// reloadRX <- struct{}{} //I'm currently not dealing with other chan
<-reload //waiting for you finished
// reloadRX <- struct{}{} //I've read all deltas, you can release them
}
}
}()
if mode == 2 {
go func() { go func() {
viewCnt++ for {
msgList := make([]T, 0) id, recv, ok := reflect.Select(selectCases)
if prevId != -1 {
selectCases[prevId].Dir = reflect.SelectRecv
selectCases[prevId].Send = reflect.Value{}
prevId = -1
}
if !ok {
// ret.used.Push(id)
//
// delete(used, id)
ret.modify <- modify_t[T]{DELETE, id - 1, nil}
<-reload[chanId]
// reloadRX <- struct{}{} //I'm currently not dealing with other chan
<-reload[chanId] //waiting for you finished
// reloadRX <- struct{}{} //I've read all deltas, you can release them
continue
}
if mode == 1 && id != 0 {
ret.RX <- To[T](recv) // possible for below to send to Chan?
if ret.reply {
msg, _ := <-ret.TX
selectCases[id].Dir = reflect.SelectSend
selectCases[id].Send = reflect.ValueOf(msg)
prevId = id
}
} else if id == 0 {
// reloadRX <- struct{}{} //I'm currently not dealing with other chan
<-reload[chanId] //waiting for you finished
// reloadRX <- struct{}{} //I've read all deltas, you can release them
}
}
}()
}
if mode == 2 {
chanId := viewCnt
viewCnt++
reload = append(reload, make(chan struct{}))
msgList := make([]T, 0)
go func() {
for { for {
select { select {
case <-reload: case <-reload[chanId]:
// reloadRX <- struct{}{} //I'm currently not dealing with other chan // reloadRX <- struct{}{} //I'm currently not dealing with other chan
<-reload //waiting for you finished <-reload[chanId] //waiting for you finished
if addQue.Length() == 0 {
continue
}
for !addQue.IsEmpty() { for !addQue.IsEmpty() {
delta := addQue.Pop() delta := addQue.Pop()
for _, x := range msgList { for _, x := range msgList {

13
fsm.go
View File

@ -12,6 +12,7 @@ const (
INCOMING globalConnEvent = iota INCOMING globalConnEvent = iota
EMPTY EMPTY
) )
const SERVER_STATE_INFO_FMTSTR = "Server is currently at %s state"
// luckily I use int for them all // luckily I use int for them all
var ( var (
@ -54,7 +55,7 @@ var waitChan chan struct{}
// no we don't need cmdChan, we just make it work immediately // no we don't need cmdChan, we just make it work immediately
func handleWaitingToRunning() { func handleWaitingToRunning() {
GetLogger().Infof("Server is currently at %s state", stateToStr[RUNNING]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[RUNNING])
waitChan <- struct{}{} waitChan <- struct{}{}
_, ok := <-waitChan _, ok := <-waitChan
if ok { if ok {
@ -62,7 +63,7 @@ func handleWaitingToRunning() {
} //else it's too late } //else it's too late
} }
func handleRunningToWaiting() { func handleRunningToWaiting() {
GetLogger().Infof("Server is currently at %s state", stateToStr[WAITING]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[WAITING])
waitChan = make(chan struct{}) waitChan = make(chan struct{})
go waitingThread() go waitingThread()
state = WAITING state = WAITING
@ -70,7 +71,7 @@ func handleRunningToWaiting() {
// TODO: work with daemon // TODO: work with daemon
func handleWaitingToStopping() { func handleWaitingToStopping() {
GetLogger().Infof("Server is currently at %s state", stateToStr[STOPPING]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[STOPPING])
go stoppingThread() go stoppingThread()
state = STOPPING state = STOPPING
} }
@ -82,7 +83,7 @@ func stoppingThread() {
handleStoppingToStopped() handleStoppingToStopped()
} }
func handleStoppingToStopped() { func handleStoppingToStopped() {
GetLogger().Infof("Server is currently at %s state", stateToStr[STOPPED]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[STOPPED])
state = STOPPED state = STOPPED
} }
func bootingThread() { func bootingThread() {
@ -95,12 +96,12 @@ func bootingThread() {
var runningChan chan struct{} var runningChan chan struct{}
func handleBootingToRunning() { func handleBootingToRunning() {
GetLogger().Infof("Server is currently at %s state", stateToStr[RUNNING]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[RUNNING])
state = RUNNING state = RUNNING
ConnSignalChan <- RUNNING ConnSignalChan <- RUNNING
} }
func handleStoppedToBooting() { func handleStoppedToBooting() {
GetLogger().Infof("Server is currently at %s state", stateToStr[BOOTING]) GetLogger().Infof(SERVER_STATE_INFO_FMTSTR, stateToStr[BOOTING])
state = BOOTING state = BOOTING
bootingThread() bootingThread()
} }

View File

@ -1,8 +1,9 @@
package main package main
import ( import (
"github.com/sirupsen/logrus"
"os" "os"
"github.com/sirupsen/logrus"
) )
var logger *logrus.Logger var logger *logrus.Logger
@ -16,6 +17,7 @@ func InitLogger() {
switch logLevel { switch logLevel {
case "debug": case "debug":
logger.SetLevel(logrus.DebugLevel) logger.SetLevel(logrus.DebugLevel)
logger.SetReportCaller(true)
case "info": case "info":
logger.SetLevel(logrus.InfoLevel) logger.SetLevel(logrus.InfoLevel)
case "warn", "warning": case "warn", "warning":