예제 #1
0
파일: auctioneer.go 프로젝트: vito/auction
func RemoteAuction(client yagnats.NATSClient, auctionRequest types.AuctionRequest) types.AuctionResult {
	guid := util.RandomGuid()
	payload, _ := json.Marshal(auctionRequest)

	c := make(chan []byte)
	client.Subscribe(guid, func(msg *yagnats.Message) {
		c <- msg.Payload
	})

	client.PublishWithReplyTo("diego.auction", guid, payload)

	var responsePayload []byte
	select {
	case responsePayload = <-c:
	case <-time.After(time.Minute):
		return types.AuctionResult{}
	}

	var auctionResult types.AuctionResult
	err := json.Unmarshal(responsePayload, &auctionResult)
	if err != nil {
		panic(err)
	}

	return auctionResult
}
예제 #2
0
func (rep *RepNatsClient) publishWithTimeout(guid string, subject string, req interface{}, resp interface{}) (err error) {
	replyTo := util.RandomGuid()
	c := make(chan []byte, 1)

	_, err = rep.client.Subscribe(replyTo, func(msg *yagnats.Message) {
		c <- msg.Payload
	})
	if err != nil {
		return err
	}

	payload := []byte{}
	if req != nil {
		payload, err = json.Marshal(req)
		if err != nil {
			return err
		}
	}

	rep.client.PublishWithReplyTo(guid+"."+subject, replyTo, payload)

	select {
	case payload := <-c:
		if string(payload) == "error" {
			return RequestFailedError
		}

		if resp != nil {
			return json.Unmarshal(payload, resp)
		}

		return nil

	case <-time.After(rep.timeout):
		// rep.client.Unsubscribe(sid)
		return TimeoutError
	}
}
예제 #3
0
func (rep *RepNatsClient) Vote(guids []string, instance instance.Instance) []types.VoteResult {
	replyTo := util.RandomGuid()

	allReceived := new(sync.WaitGroup)
	responses := make(chan types.VoteResult, len(guids))

	buffer := &bytes.Buffer{}
	lock := &sync.Mutex{}
	_, err := rep.client.Subscribe(replyTo, func(msg *yagnats.Message) {
		defer func() {
			if r := recover(); r != nil {
				lock.Lock()
				fmt.Println(buffer)
				lock.Unlock()
				panic(r)
			}
		}()
		defer allReceived.Done()
		var result types.VoteResult
		err := json.Unmarshal(msg.Payload, &result)
		if err != nil {
			return
		}

		lock.Lock()
		fmt.Fprintf(buffer, "REC: %s %s %s\n", replyTo, msg.Subject, result.Rep)
		lock.Unlock()
		responses <- result
	})

	if err != nil {
		return []types.VoteResult{}
	}

	payload, _ := json.Marshal(instance)

	allReceived.Add(len(guids))

	for _, guid := range guids {
		lock.Lock()
		fmt.Fprintf(buffer, "REQ: %s %s\n", guid, replyTo)
		lock.Unlock()
		rep.client.PublishWithReplyTo(guid+".vote", replyTo, payload)
	}

	done := make(chan struct{})
	go func() {
		allReceived.Wait()
		close(done)
	}()

	select {
	case <-done:
	case <-time.After(rep.timeout):
		println("TIMING OUT!!")
	}

	results := []types.VoteResult{}

	for {
		select {
		case res := <-responses:
			results = append(results, res)
		default:
			return results
		}
	}

	return results
}