Example #1
0
File: sync.go Project: jimjh/octopi
// ackFollower sends an acknowledgement to the follower.
func (b *Broker) ackFollower(f *Follower) error {

	b.lock.Lock()
	defer b.lock.Unlock()

	ack := new(protocol.Ack)
	if b.role != LEADER || f.conn.RemoteAddr().String() == b.Origin() {
		log.Warn("Denying follow requests from %s.", f.conn.RemoteAddr())
		ack.Status = protocol.StatusFailure
	} else {

		inner := new(protocol.FollowACK)
		inner.Truncate = make(Offsets)
		for topic, checkpoint := range b.checkpoints {
			log.Info("Checkpoint is %v", checkpoint)
			if f.tails[topic] > checkpoint {
				inner.Truncate[topic] = checkpoint
				f.tails[topic] = checkpoint
			}
		}

		ack.Status = protocol.StatusSuccess
		ack.Payload, _ = json.Marshal(inner)

	}

	return websocket.JSON.Send(f.conn, ack)

}
Example #2
0
// producer handles incoming produce requests. Producers may send multiple
// produce requests on the same persistent connection. The function exits when
// an `io.EOF` is received on the connection.
func producer(conn *websocket.Conn) {

	defer conn.Close()

	for {

		var request protocol.ProduceRequest

		err := websocket.JSON.Receive(conn, &request)
		if err == io.EOF { // graceful shutdown
			break
		}

		if nil != err {
			log.Warn("Ignoring invalid message from %v.", conn.RemoteAddr())
			continue
		}

		ack := new(protocol.Ack)
		if err := broker.Publish(request.Topic, request.ID, &request.Message); nil != err {
			log.Error(err.Error())
			ack.Status = protocol.StatusFailure
		} else {
			ack.Status = protocol.StatusSuccess
		}
		// TODO: should redirect if this node is not the leader

		websocket.JSON.Send(conn, &ack)

	}

	log.Info("Closed producer connection from %v.", conn.RemoteAddr())

}