func iNewLspServer(port int, params *LspParams) (*LspServer, error) {
	srv := new(LspServer)
	srv.nextId = 1
	if params == nil {
		// Insert default parameters
		params = &LspParams{5, 2000}
	}
	srv.params = params
	hostport := fmt.Sprintf(":%v", port)
	addr, err := lspnet.ResolveUDPAddr("udp", hostport)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	srv.udpConn, err = lspnet.ListenUDP("udp", addr)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	srv.readBuf = NewBuf()
	// Need enough room to recycle close messages
	srv.appReadChan = make(LspMessageChan, 1)
	srv.appWriteChan = make(LspMessageChan)
	srv.netInChan = make(networkChan)
	srv.epochChan = make(chan int)
	srv.connById = make(map[uint16]*lspConn)
	srv.connByAddr = make(map[string]*lspConn)
	srv.closeReplyChan = make(chan error, 1)
	srv.closeAllReplyChan = make(chan error, 1)
	srv.writeReplyChan = make(chan error, 1)

	go srv.serverLoop()
	go srv.udpReader()
	go epochTrigger(srv.params.EpochMilliseconds, srv.epochChan, &srv.stopGlobalNetworkFlag)
	return srv, nil
}
func NewTribserver(agencyid, master, ownstorage, myhostport string, prefer int) *Tribserver {
	lsplog.SetVerbose(3)

	//Connect to master
	lc, err := libconn.NewLibconn(agencyid, master, myhostport, prefer)
	if lsplog.CheckReport(1, err) {
		return nil
	}

	//Init libstore : Agency storage server
	ls, err := libstore.NewLibstore(agencyid, ownstorage, myhostport, libstore.NONE)
	if lsplog.CheckReport(1, err) {
		log.Printf("[%s:%s] Fail to start", agencyid, myhostport)
		return nil
	}

	//Init libairline : Airline storage server
	la, err := libairline.NewLibairline(lc, agencyid, myhostport)
	if lsplog.CheckReport(1, err) {
		log.Printf("[%s:%s] Fail to start", agencyid, myhostport)
		return nil
	}

	//lsplog.Vlogf(5, "Server active... %s", myhostport);
	log.Printf("[%s:%s] Start", agencyid, myhostport)
	return &Tribserver{ls, la, agencyid, myhostport}
}
Exemple #3
0
//Broadcast message to all replicas
func (lp *Libpaxos) broadcast(PacketMsg *Msg) {
	if PacketMsg != nil {
		//lsplog.Vlogf(6, "[Libpaxos] Broadcast type: %d", PacketMsg.MsgType)

		p := Packet{}
		p.PacketFrom = lp.self
		p.PacketMsg = *PacketMsg

		var reply Reply
		for _, r := range lp.replicas {
			//			if r == lp.self {
			//				continue
			//			}

			//lsplog.Vlogf(6, "[Libpaxos] Broadcast: %s", r)

			client, err := rpc.DialHTTP("tcp", r)
			if lsplog.CheckReport(6, err) {
				lsplog.Vlogf(6, "[Libpaxos] Broadcast to %s failed", r)
				//client.Close()
				continue
			}

			err = client.Call("Libpaxos.ReceiveMessage", p, &reply)
			if lsplog.CheckReport(1, err) {
				lsplog.Vlogf(6, "[Libpaxos] Broadcast call to %s failed", r)
			}
			client.Close()
		}
	}
}
// Write message to UDP connection.  Address already registered with connection
func (cli *LspClient) udpWrite(msg *LspMessage) {
	b := msg.genPacket()
	_, err := cli.udpConn.Write(b)
	if lsplog.CheckReport(6, err) {
		cli.Vlogf(6, "Write failed\n")
	}
}
// Shutting down network communications
func (cli *LspClient) stopNetwork() {
	cli.lspConn.stopNetworkFlag = true
	err := cli.udpConn.Close()
	if lsplog.CheckReport(4, err) {
		lsplog.Vlogf(6, "Client Continuing\n")
	}
}
func (la *Libairline) CreateFlight(flight airlineproto.FlightInfo) error {
	log.Printf("[%s:%s] Start to add flight: %s\n", la.agencyid, la.myhostport, flight.ID)

	conn, err := la.lib_conn.GetServer(tribproto.GetAirlineFromFlightId(flight.ID))
	if err != nil {
		log.Printf("[%s:%s] Fail to add flight: %s\n", la.agencyid, la.myhostport, flight.ID)
		return lsplog.MakeErr("Airline doesn't exist")
	}

	args := &airlineproto.PutArgs{flight.ID, flight}
	var reply airlineproto.PutReply
	err = conn.Call("AirlineRPC.CreateFlight", args, &reply)
	if lsplog.CheckReport(2, err) {
		log.Printf("[%s:%s] Fail to add flight: %s\n", la.agencyid, la.myhostport, flight.ID)
		return lsplog.MakeErr("Flight already exist")
	}

	if reply.Status != airlineproto.OK {
		log.Printf("[%s:%s] Fail to add flight: %s\n", la.agencyid, la.myhostport, flight.ID)
		return lsplog.MakeErr("Flight already exist")
	}

	log.Printf("[%s:%s] Succeed to add flight: %s\n", la.agencyid, la.myhostport, flight.ID)
	return nil
}
func (tl *TranLayer) BookingFlights(orderList []tranlayerproto.Order) error {

	// find server for each airline company
	tranOrderList := make([]*tranOrder, len(orderList))

	for i, order := range orderList {
		conn, pptID, err := tl.lib_conn.GetServerWithAddress(order.AirlineID)
		if lsplog.CheckReport(2, err) {
			return err
		}
		tranOrderList[i] = &tranOrder{order.FlightID, pptID, order.Amount, conn}
	}

	// get unique transaction id
	tranID := fmt.Sprintf("%s:%d", tl.myhostport, time.Now().UnixNano())
	lsplog.Vlogf(5, "Begin transaction:"+tranID)
	// send request to store handler
	req := &reqContent{INIT_TRANS, tranID, tranOrderList}
	replyc := make(chan interface{})
	tl.reqChan <- &Request{req, replyc}
	// wait for response
	status := (<-replyc).(bool)
	lsplog.Vlogf(5, "End of transaction:"+tranID)
	if status {
		return nil
	}
	return lsplog.MakeErr("Transaction Failed")
}
// Shut down all network activity
func (srv *LspServer) stopGlobalNetwork() {
	srv.stopGlobalNetworkFlag = true
	err := srv.udpConn.Close()
	if lsplog.CheckReport(4, err) {
		lsplog.Vlogf(6, "Server Continuing\n")
	}
}
// Write message to UDP connection.  Address specified by con
func (srv *LspServer) udpWrite(con *lspConn, msg *LspMessage) {
	b := msg.genPacket()
	_, err := srv.udpConn.WriteToUDP(b, con.addr)
	if lsplog.CheckReport(6, err) {
		srv.Vlogf(6, "Write failed\n")
	}
}
Exemple #10
0
func (ts *Tribserver) GetBookings(args *tribproto.GetBookingsArgs, reply *tribproto.GetBookingsReply) error {
	lsplog.Vlogf(5, "Get bookings: "+args.Userid)

	flightids, err := ts.lib_store.GetList(getUserBookingsKey(args.Userid), ts.agencyid)
	if lsplog.CheckReport(3, err) {
		reply.Status = tribproto.ENOSUCHUSER
		return nil
	}

	flightsInfo, ferr := ts.doGetFlightsFromIds(flightids)
	if lsplog.CheckReport(3, ferr) {
		return ferr
	}
	reply.Flights = flightsInfo
	reply.Status = tribproto.OK
	return nil
}
Exemple #11
0
func (ts *Tribserver) ViewFlights(args *tribproto.ViewFlightsArgs, reply *tribproto.ViewFlightsReply) error {
	lsplog.Vlogf(5, "Get flights:"+args.From+" to:"+args.To+" date:"+args.DepartureDate)

	flightids, err := ts.lib_airline.GetAllFlights(args.From, args.To, args.DepartureDate)
	if lsplog.CheckReport(3, err) {
		return lsplog.MakeErr("Error fetching flight ids")
	}

	flightsInfo, ferr := ts.doGetFlightsFromIds(flightids)
	if lsplog.CheckReport(3, ferr) {
		return ferr
	}

	reply.Flights = flightsInfo
	reply.Status = tribproto.OK
	return nil
}
// Goroutine that reads messages from UDP connection and writes to message channel
func (cli *LspClient) udpReader() {
	udpConn := cli.udpConn
	mc := cli.netInChan
	var buffer [1500]byte
	for !cli.lspConn.stopNetworkFlag {
		n, _, err := udpConn.ReadFromUDP(buffer[0:])
		if lsplog.CheckReport(1, err) {
			cli.Vlogf(6, "Client continuing\n")
			continue
		}
		m, merr := extractMessage(buffer[0:n])
		if lsplog.CheckReport(1, merr) {
			cli.Vlogf(6, "Client continuing\n")
			continue
		}
		mc <- m
	}
}
Exemple #13
0
func (ts *Tribserver) CreateUser(args *tribproto.CreateUserArgs, reply *tribproto.CreateUserReply) error {
	//Check for existing user
	if ts.doesUserExist(args.Userid) {
		reply.Status = tribproto.EEXISTS
		return nil
	}

	// Create empty bookings entry for user
	cerr := ts.lib_store.Put(getNewUserKey(args.Userid), "new_user", ts.agencyid)
	perr := ts.lib_store.Put(getUserBookingsKey(args.Userid), "", ts.agencyid)
	if lsplog.CheckReport(3, cerr) || lsplog.CheckReport(3, perr) {
		return lsplog.MakeErr("Error creating user")
	}

	lsplog.Vlogf(5, "Created user:"+args.Userid)
	reply.Status = tribproto.OK
	return nil
}
func (la *Libairline) GetFlight(flightid string) (airlineproto.FlightInfo, error) {
	conn, err := la.lib_conn.GetServer(tribproto.GetAirlineFromFlightId(flightid))
	if lsplog.CheckReport(2, err) {
		return airlineproto.FlightInfo{}, err
	}

	args := &airlineproto.GetArgs{flightid, false, ""}
	var reply airlineproto.GetReply
	err = conn.Call("AirlineRPC.GetFlight", args, &reply)
	if lsplog.CheckReport(2, err) {
		return airlineproto.FlightInfo{}, err
	}

	if reply.Status != airlineproto.OK {
		return airlineproto.FlightInfo{}, lsplog.MakeErr("Fetch flight failed")
	}

	return reply.FlightInfo, nil
}
// Goroutine that reads messages from UDP connection and writes to message channel
func (srv *LspServer) udpReader() {
	udpConn := srv.udpConn
	netc := srv.netInChan
	var buffer [1500]byte
	for !srv.stopGlobalNetworkFlag {
		n, addr, err := udpConn.ReadFromUDP(buffer[0:])
		if lsplog.CheckReport(1, err) {
			srv.Vlogf(5, "Server continuing\n")
			continue
		}
		m, merr := extractMessage(buffer[0:n])
		if lsplog.CheckReport(1, merr) {
			srv.Vlogf(6, "Server continuing\n")
			continue
		}
		srv.Vlogf(5, "Received message %s\n", m)
		d := &networkData{m, addr}
		netc <- d
	}
}
func iNewLspClient(hostport string, params *LspParams) (*LspClient, error) {
	cli := new(LspClient)
	if params == nil {
		// Insert default parameters
		params = &LspParams{5, 2000}
	}
	cli.params = params
	addr, err := lspnet.ResolveUDPAddr("udp", hostport)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	cli.lspConn = newConn(addr, 0, 0)
	// Client's first received message will be data message.
	cli.lspConn.nextRecvSeqNum = NextSeqNum(0)
	cli.udpConn, err = lspnet.DialUDP("udp", nil, addr)
	if lsplog.CheckReport(1, err) {
		return nil, err
	}
	// Need enough room to recycle close messages at end
	cli.appReadChan = make(LspMessageChan, 2)
	cli.readBuf = NewBuf()
	cli.appWriteChan = make(LspMessageChan, 1)
	cli.netInChan = make(LspMessageChan, 1)
	cli.epochChan = make(chan int)
	cli.closeReplyChan = make(chan error, 2)
	cli.writeReplyChan = make(chan error, 2)

	go cli.clientLoop()
	go cli.udpReader()
	go epochTrigger(cli.params.EpochMilliseconds, cli.epochChan, &cli.lspConn.stopNetworkFlag)
	// Send connection request to server
	nm := GenConnectMessage()
	cli.udpWrite(nm)
	cli.lspConn.pendingMsg = nm
	cli.lspConn.nextSendSeqNum = NextSeqNum(0)
	cm := <-cli.appReadChan
	if cm.Type == MsgCONNECT {
		return cli, nil
	}
	return nil, lsplog.MakeErr("Connection failed")
}
func NewLibairline(lc *libconn.Libconn, agencyid, myhostport string) (*Libairline, error) {
	la := &Libairline{}

	la.lib_conn = lc
	la.agencyid = agencyid
	la.myhostport = myhostport

	trnlayer, err := tranlayer.NewTranLayer(lc, agencyid, myhostport)
	if lsplog.CheckReport(2, err) {
		return nil, err
	}

	// Declare existense
	err = lc.DeclareExistence()
	if lsplog.CheckReport(2, err) {
		return nil, err
	}

	la.lib_tranlayer = trnlayer
	return la, nil
}
Exemple #18
0
func (ts *Tribserver) doGetFlightsFromIds(flightids []string) ([]airlineproto.FlightInfo, error) {
	flightsInfo := make([]airlineproto.FlightInfo, len(flightids))
	for i, fid := range flightids {
		f, err := ts.lib_airline.GetFlight(fid)
		lsplog.Vlogf(6, "Flight id "+fid)
		if lsplog.CheckReport(3, err) {
			return nil, lsplog.MakeErr("Error fetching flight from flight id")
		}
		flightsInfo[i] = f
	}

	return flightsInfo, nil
}
Exemple #19
0
func (lc *Libconn) appendList(key, value string) error {
	args := &storageproto.PutArgs{key, value}
	var reply storageproto.PutReply
	err := lc.conn.Call("StorageRPC.AppendToList", args, &reply)
	if lsplog.CheckReport(2, err) {
		//log.Printf("[%s:%s] Airline already declared\n", lc.entityid, lc.myhostport)
		return lsplog.MakeErr("Declare existense failed")
	}
	if reply.Status != storageproto.OK {
		//log.Printf("[%s:%s] Airline already declared\n", lc.entityid, lc.myhostport)
		return lsplog.MakeErr("Declare Existense Failed")
	}

	return nil
}
func (la *Libairline) MakeBooking(flightids []string, isRemove bool) error {
	//TODO: Handle remove
	orderQuantity := 1

	if isRemove {
		orderQuantity = -1
	}

	orderGrpMap := make(map[string]*bufi.Buf)

	for _, v := range flightids {
		airlineId := tribproto.GetAirlineFromFlightId(v)
		orderList, exist := orderGrpMap[airlineId]
		if exist == false {
			orderList = bufi.NewBuf()
		}
		orderList.Insert(v)
		orderGrpMap[airlineId] = orderList
	}

	orders := make([]tranlayerproto.Order, len(orderGrpMap))
	i := 0
	for airlineId, orderList := range orderGrpMap {
		flightIds := ""
		for !orderList.Empty() {
			flightId := orderList.Remove().(string)
			if flightIds == "" {
				flightIds = flightId
			} else {
				flightIds = fmt.Sprintf("%s:%s", flightIds, flightId)
			}
		}

		order := tranlayerproto.Order{airlineId, flightIds, orderQuantity}
		orders[i] = order
		i++
	}
	err := la.lib_tranlayer.BookingFlights(orders)
	if lsplog.CheckReport(2, err) {
		return err
	}

	return nil
}
Exemple #21
0
//TODO: Cache connections
func NewLibconn(entityid, master, myhostport string, prefer int) (*Libconn, error) {
	lc := &Libconn{}

	lc.connLock = new(sync.Mutex)
	lc.connMap = make(map[int]*rpc.Client)
	lc.entityid = entityid
	lc.master = master
	lc.myhostport = myhostport
	lc.prefer = prefer

	//Connect to master node
	cli, err := rpc.DialHTTP("tcp", master)
	if lsplog.CheckReport(2, err) {
		return nil, err
	}
	lc.conn = cli

	return lc, nil
}
func NewAirlineServer(airlineID, myhostport, masterStorage, ownStorage string, replicas []string, pos int) (*AirlineServer, *libpaxos.Libpaxos, error) {
	lsplog.SetVerbose(4)
	as := &AirlineServer{}
	as.cmdNO = 0
	as.reqChan = make(chan *Request)
	as.airlineID = airlineID
	as.myhostport = myhostport
	as.logBuf = make(map[string](*bufi.Buf))
	as.flightBuf = make(map[string](*airlineproto.FlightInfo))
	as.flightQueryBuf = make(map[string](string))
	as.lockBuf = make(map[string](bool))
	as.oldLog = make(map[string]int)
	as.oldReplycMap = make(map[int](chan interface{}))

	q := len(replicas)/2 + len(replicas)%2
	as.lp = libpaxos.NewLibpaxos(myhostport, replicas, q, pos, as)

	lc, err := libconn.NewLibconn(airlineID, masterStorage, myhostport, 0)
	if lsplog.CheckReport(2, err) {
		return nil, nil, err
	}
	as.lib_conn = lc

	//
	//	// Create RPC connection to own storage server
	//	conn2, err := rpc.DialHTTP("tcp", ownStorage)
	//	if err != nil {
	//		return nil, err
	//	}
	//	as.ownStorage = conn2
	//
	// Declare existense
	lc.PublishAirline()
	lc.DeclareExistence()

	go as.storeHandler()
	log.Printf("[%s:%s] Start", airlineID, myhostport)
	return as, as.lp, nil
}
func (la *Libairline) GetAllFlights(from, to, dep string) ([]string, error) {
	log.Printf("[%s:%s] Start to get flights from %s to %s, on %s\n", la.agencyid, la.myhostport, from, to, dep)
	conns, err := la.lib_conn.GetServers()
	if err != nil {
		log.Printf("[%s:%s] Fail to get flights from %s to %s, on %s\n", la.agencyid, la.myhostport, from, to, dep)
		return nil, err
	}

	flightMap := make(map[string]bool)
	for _, conn := range conns {
		args := &airlineproto.GetAllArgs{from, to, dep}
		var reply airlineproto.GetAllReply
		err := conn.Call("AirlineRPC.GetAllFlightIDs", args, &reply)
		if lsplog.CheckReport(2, err) {
			log.Printf("[%s:%s] Fail to get flights from %s to %s, on %s\n", la.agencyid, la.myhostport, from, to, dep)
			return nil, err
		}

		if reply.Status != airlineproto.OK {
			log.Printf("[%s:%s] Fail to get flights from %s to %s, on %s\n", la.agencyid, la.myhostport, from, to, dep)
			return nil, lsplog.MakeErr("Fetch all flights failed")
		}
		for _, flight := range reply.FlightIDs {
			flightMap[flight] = true
		}
	}

	flights := make([]string, len(flightMap))
	i := 0
	for flight, _ := range flightMap {
		flights[i] = flight
		i++
	}

	log.Printf("[%s:%s] Succeed to get flights from %s to %s, on %s\n", la.agencyid, la.myhostport, from, to, dep)
	return flights, nil
}
Exemple #24
0
func (ts *Tribserver) doBookingTransaction(isRemove bool, args *tribproto.BookingArgs, reply *tribproto.BookingReply) error {
	if !ts.doesUserExist(args.Userid) {
		reply.Status = tribproto.ENOSUCHUSER
		return nil
	}

	_, ferr := ts.doGetFlightsFromIds(args.FlightIds)
	if lsplog.CheckReport(3, ferr) {
		reply.Status = tribproto.EBOOKINGFAILED
		return nil
	}

	// Do not attempt to decrement count if duplicate booking

	flights, err := ts.lib_store.GetList(getUserBookingsKey(args.Userid), ts.agencyid)
	if lsplog.CheckReport(3, err) {
		reply.Status = tribproto.EBOOKINGFAILED
		return nil
	}

	fmt.Println("tribimpl@", flights)
	exist := false
	for _, fid1 := range args.FlightIds {
		for _, fid2 := range flights {
			if fid1 == fid2 {
				exist = true

			}
		}
	}

	if !isRemove {
		if exist == true {
			reply.Status = tribproto.EEXISTS
			return nil
		}
	} else {
		if exist == false {
			reply.Status = tribproto.ENOTBOOKED
			return nil
		}
	}

	err = ts.lib_airline.MakeBooking(args.FlightIds, isRemove)
	if err != nil {
		reply.Status = tribproto.EBOOKINGFAILED
		return nil
	}

	//If successful add to user bookings list
	for _, fid := range args.FlightIds {
		var err error
		if !isRemove {
			err = ts.lib_store.AppendToList(getUserBookingsKey(args.Userid), fid, ts.agencyid)
		} else {

			err = ts.lib_store.RemoveFromList(getUserBookingsKey(args.Userid), fid, ts.agencyid)
		}
		if lsplog.CheckReport(3, err) {
			reply.Status = tribproto.EBOOKINGFAILED
			return err
		}
	}

	reply.Status = tribproto.OK
	return nil
}