// NewGameServer creates an instance of a Game Server. It does not return // until it has successfully joined the cluster of game servers and started // its libpaxos service. func NewGameServer(centralServerHostPort, hostname string, port int, pattern string) (GameServer, error) { // RPC Dial to the central server to join the ring c, err := rpc.DialHTTP("tcp", centralServerHostPort) if err != nil { fmt.Println("Could not connect to central server host port via RPC") fmt.Println(err) return nil, err } // Register myself with the central server, obtaining my ID, and a // complete list of all servers in the ring. gshostport := fmt.Sprintf("%s:%d", hostname, port) args := ¢ralrpc.RegisterGameServerArgs{gshostport} var reply centralrpc.RegisterGameServerReply reply.Status = centralrpc.NotReady for reply.Status != centralrpc.OK { err = c.Call("CentralServer.RegisterGameServer", args, &reply) if err != nil { fmt.Println("Could not RPC call method CentralServer.RegisterGameServer") fmt.Println(err) return nil, err } if reply.Status == centralrpc.Full { return nil, errors.New("Could not register with central server, ring FULL") } time.Sleep(REGISTER_RETRY_INTERVAL * time.Millisecond) } // Start the libpaxos service newlibpaxos, err := libpaxos.NewLibpaxos(reply.GameServerID, gshostport, reply.Servers) if err != nil { fmt.Println("Could not start libpaxos") fmt.Println(err) return nil, err } // Websockets client related stuff clients := make(map[int]*client) addCh := make(chan *client) delCh := make(chan *client) doneCh := make(chan bool) errCh := make(chan error) // Debugging setup var vOut, eOut io.Writer if LOG_TO_FILE { now := time.Now().String() var err1, err2 error vOut, err1 = os.Create(fmt.Sprintf("%d_debug_%s.log", reply.GameServerID, now)) eOut, err2 = os.Create(fmt.Sprintf("%d_error_%s.log", reply.GameServerID, now)) if err1 != nil || err2 != nil { panic(err) } } else { vOut = os.Stdout eOut = os.Stderr } LOGV = util.NewLogger(DEBUG_LOG, "DEBUG", vOut) LOGE = util.NewLogger(ERROR_LOG, "ERROR", eOut) gs := &gameServer{ reply.GameServerID, hostname, port, gshostport, newlibpaxos, pattern, sync.Mutex{}, clients, addCh, delCh, doneCh, errCh, 0, make(chan *paxosrpc.ProposalValue, 1000), len(reply.Servers), lib2048.NewGame2048(), make(chan *util.Game2048State, 1000), make(chan *lib2048.Move, 1000), } gs.libpaxos.DecidedHandler(gs.handleDecided) LOGV.Printf("GS node %d loaded libpaxos\n", reply.GameServerID) go gs.ListenForClients() go gs.processMoves() go gs.clientTasker() go gs.clientMasterHandler() return gs, nil }
"time" ) type cclient struct { conn *websocket.Conn game lib2048.Game2048 movelist []lib2048.Direction quitchan chan int stophandler chan int stopsender chan int stopreceiver chan int moveQueue chan util.ClientMove cserv string } var LOGV = util.NewLogger(false, "CMDLINECLIENT", os.Stdout) var LOGE = util.NewLogger(true, "CMDLINECLIENT", os.Stderr) func NewCClient(cservAddr string, gameServHostPort string, interval int) (Cclient, error) { ws, err := doConnect(cservAddr, gameServHostPort) if err != nil { return nil, err } game := lib2048.NewGame2048() cc := &cclient{ ws, game, make([]lib2048.Direction, 0), make(chan int), make(chan int), make(chan int),
"errors" "fmt" "math" "net" "net/http" "net/rpc" "os" "sync" ) const ( ERROR_LOG bool = true DEBUG_LOG bool = false ) var LOGV = util.NewLogger(DEBUG_LOG, "DEBUG", os.Stdout) var LOGE = util.NewLogger(ERROR_LOG, "ERROR", os.Stderr) type gameServer struct { info paxosrpc.Node clientCount int } type centralServer struct { nextGameServerID uint32 gameServersLock sync.Mutex gameServers map[uint32]*gameServer hostPortToGameServer map[string]*gameServer gameServersSlice []paxosrpc.Node numGameServers int }
package main import ( "distributed2048/cmdlineclient" "distributed2048/lib2048" "distributed2048/util" "flag" "fmt" "os" "strings" "time" ) var LOGV = util.NewLogger(false, "LIBSTORETEST", os.Stdout) var ( numClients = flag.Int("numClients", 1, "number of game clients") // numGameServers = flag.Int("numGameServers", 1, "number of game servers") gameServerHostPorts = flag.String("gsHostPorts", "", "comma separated list of host:port for each game server") centralServerHostPort = flag.String("csHostPort", fmt.Sprintf("localhost:%d", util.CENTRALPORT), "host:port of central server") numMoves = flag.Int("numMoves", 10, "number of random moves to generate") numSendingClients = flag.Int("numSendingClients", 1, "number of clients that will be sending moves") sendMoveInterval = flag.Int("sendMoveInterval", 1000, "number of milliseconds between sending moves") ) type testFunc struct { name string f func() } func test() bool {