Example #1
0
func sendMessageAndExpectAnAck(stream *comm.Stream, dead chan bool, message *messages.Message) {
	err := stream.WriteMessage(message)
	if err != nil {
		log.Printf("Unable to send message to client: %v\n", err)
		dead <- true
		return
	}

	expectedAck := messages.MessageAck{
		Partition: message.Partition,
		Offset:    message.Offset,
	}
	acks[expectedAck] = make(chan bool)

	go func() {
		select {
		case _ = <-acks[expectedAck]:
			break
		case <-time.After(50 * time.Millisecond):
			if !message.IsAckRequest {
				blackHole.inbox <- *message
			}
			dead <- true
		}
		delete(acks, expectedAck)
	}()
}
Example #2
0
func handleClient(stream *comm.Stream) {
	defer stream.Close()
	var instanceId string

	instanceId, err := stream.ReadLine()
	if err != nil {
		log.Printf("Unable to identify client: %v\n", err)
		return
	}

	if instanceId == "-PING\n" {
		log.V(1).Printf("got ping: -PING; answering with: +PONG\n")
		err = stream.WriteLine("+PONG")
		if err != nil {
			log.Printf("Unable to answer with +PONG: %v\n", err)
		}
		return
	}

	log.V(1).Printf("got client: %s\n", instanceId)

	inbox := make(chan messages.Message, CHANNEL_BUFFER_SIZE)
	client := clientInbox{
		inbox: inbox,
		count: 1,
	}
	addClient(instanceId, client)

	ackErrors := make(chan error)

	go func() {
		for {
			var ack messages.MessageAck
			err = stream.ReadMessage(&ack)
			if err != nil {
				ackErrors <- err
				continue
			}

			if _, found := acks[ack]; found {
				log.V(2).Printf("Got ack: %v\n", ack)
				acks[ack] <- true
			}
		}
	}()

	dead := make(chan bool)
	for {
		select {
		case message := <-inbox:
			go sendMessageAndExpectAnAck(stream, dead, &message)

		case <-time.Tick(75 * time.Millisecond):
			go sendMessageAndExpectAnAck(stream, dead, ackRequest)

		case err := <-ackErrors:
			log.V(3).Printf("Got ack error: %v\n", err)
		case <-dead:
			log.V(2).Printf("Client %v disconnected\n", instanceId)
			clientDead(instanceId)
		}
	}
}