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 }
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 } }
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 }