// 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 := &centralrpc.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
}
Example #4
0
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 {