wfc-server/common/connection.go

102 lines
2.4 KiB
Go

package common
import (
"net/rpc"
"time"
"wwfc/logging"
)
var rpcFrontend *rpc.Client
type RPCFrontendPacket struct {
Server string
Index uint64
Data []byte
}
// ConnectFrontend connects to the frontend RPC server
func ConnectFrontend() {
config := GetConfig()
var err error
for i := 0; rpcFrontend == nil; i++ {
rpcFrontend, err = rpc.Dial("tcp", config.BackendFrontendAddress)
if err != nil {
if i > 20 {
panic(err)
}
// Sleep for 200 ms before trying again
<-time.After(200 * time.Millisecond)
}
}
}
// SendPacket is used by backend servers to send a packet to a connection
func SendPacket(server string, index uint64, data []byte) error {
if rpcFrontend == nil {
ConnectFrontend()
}
err := rpcFrontend.Call("RPCFrontendPacket.SendPacket", RPCFrontendPacket{Server: server, Index: index, Data: data}, nil)
if err != nil {
logging.Error("COMMON", "Failed to send packet to frontend:", err)
}
return err
}
// CloseConnection is used by backend servers to close a connection
func CloseConnection(server string, index uint64) error {
if rpcFrontend == nil {
ConnectFrontend()
}
err := rpcFrontend.Call("RPCFrontendPacket.CloseConnection", RPCFrontendPacket{Server: server, Index: index}, nil)
if err != nil {
logging.Error("COMMON", "Failed to close connection:", err)
}
return err
}
// Ready will notify the frontend that the backend is ready to accept connections
func Ready() error {
if rpcFrontend == nil {
ConnectFrontend()
}
err := rpcFrontend.Call("RPCFrontendPacket.Ready", struct{}{}, nil)
if err != nil {
logging.Error("COMMON", "Failed to notify frontend that backend is ready:", err)
}
return err
}
// Shutdown will notify the frontend that the backend is shutting down
func Shutdown() (string, error) {
if rpcFrontend == nil {
ConnectFrontend()
}
var stateUuid string
err := rpcFrontend.Call("RPCFrontendPacket.ShutdownBackend", struct{}{}, &stateUuid)
if err != nil {
logging.Error("COMMON", "Failed to notify frontend that backend is shutting down:", err)
}
return stateUuid, err
}
// VerifyState will verify the state UUID with the frontend
func VerifyState(stateUuid string) (bool, error) {
if rpcFrontend == nil {
ConnectFrontend()
}
valid := false
err := rpcFrontend.Call("RPCFrontendPacket.VerifyState", stateUuid, &valid)
if err != nil {
logging.Error("COMMON", "Failed to verify state UUID with frontend:", err)
}
return valid, err
}