Beispiel #1
0
// NewPeer creates and returns a new Peer for communicating with AMQP brokers.
func NewPeer(host string) (*Peer, error) {
	conn, err := amqp.Dial("amqp://" + host)
	if err != nil {
		return nil, err
	}

	channel, err := conn.Channel()
	if err != nil {
		return nil, err
	}

	queue, err := channel.QueueDeclare(
		broker.GenerateName(), // name
		false, // not durable
		false, // delete when unused
		true,  // exclusive
		false, // no wait
		nil,   // arguments
	)
	if err != nil {
		return nil, err
	}

	err = channel.ExchangeDeclare(
		exchange, // name
		"fanout", // type
		false,    //  not durable
		false,    // auto-deleted
		false,    // internal
		false,    // no wait
		nil,      // arguments
	)
	if err != nil {
		return nil, err
	}

	return &Peer{
		conn:    conn,
		queue:   queue,
		channel: channel,
		send:    make(chan []byte),
		errors:  make(chan error, 1),
		done:    make(chan bool),
	}, nil
}
Beispiel #2
0
// Subscribe prepares the peer to consume messages.
func (n *Peer) Subscribe() error {
	consumer, err := nsq.NewConsumer(topic, broker.GenerateName(), nsq.NewConfig())
	if err != nil {
		return err
	}

	consumer.AddHandler(nsq.HandlerFunc(func(message *nsq.Message) error {
		n.messages <- message.Body
		return nil
	}))

	if err := consumer.ConnectToNSQD(n.host); err != nil {
		return err
	}

	n.consumer = consumer
	return nil
}
Beispiel #3
0
func NewPeer(host string) (*Peer, error) {
	p := &Peer{}
	p.client = amps.NewClient("client")
	p.client.MessageHandler = p
	p.client.ErrorHandler = p
	err := p.client.Connect("localhost:5000")
	for err != nil {
		err = p.client.Connect("localhost:5000")
	}
	if err == nil {
		p.wrchan = make(chan []byte, 4096)
		p.readchan = make(chan []byte, 4096)
		p.errchan = make(chan error)
		p.wrmsg.Command = "p"
		p.wrmsg.Topic = "queue"
	} else {
		fmt.Printf("PEER ERROR %s\n", err)
	}
	go func() {
		for {
			data := <-p.wrchan
			p.wrmsg.Data = string(data)
			err := p.client.Send(&p.wrmsg)
			if err != nil {
				break
			}
		}
	}()

	// logon
	logonMessage := amps.Message{
		Command: "logon",
		AckType: "processed",
		UserId:  broker.GenerateName(),
	}
	p.client.Send(&logonMessage)
	<-p.readchan

	return p, nil
}
Beispiel #4
0
// Subscribe prepares the peer to consume messages.
func (c *Peer) Subscribe() error {
	// Subscription names must start with a lowercase letter, end with a
	// lowercase letter or number, and contain only lowercase letters, numbers,
	// dashes, underscores or periods.
	c.subscription = strings.ToLower(fmt.Sprintf("x%sx", broker.GenerateName()))
	exists, err := pubsub.SubExists(c.context, c.subscription)
	if err != nil {
		return err
	}

	if exists {
		return fmt.Errorf("Subscription %s already exists", c.subscription)
	}

	if err := pubsub.CreateSub(c.context, c.subscription, topic, 0, ""); err != nil {
		return err
	}

	go c.ack()

	go func() {
		// TODO: Can we avoid using atomic flag?
		for atomic.LoadInt32(&c.stopped) != stopped {
			messages, err := pubsub.PullWait(c.context, c.subscription, bufferSize)
			if err != nil {
				// Timed out.
				continue
			}

			ids := make([]string, len(messages))
			for i, message := range messages {
				ids[i] = message.AckID
				c.messages <- message.Data
			}
			c.acks <- ids
		}
	}()
	return nil
}