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 runSimulation(natsClient yagnats.NATSClient) { simulationLock = &sync.Mutex{} simulationWait = &sync.WaitGroup{} taskTracker = map[string]*taskData{} msg := stagingMessage{ Count: nTasks, MemoryMB: taskMemory, } payload, err := json.Marshal(msg) if err != nil { panic(err) } t := time.Now() logger.Info("simulation.start", nTasks) simulationWait.Add(nTasks) _, err = natsClient.Subscribe("info.stager.*.staging-request.desire", func(msg *yagnats.Message) { var desiredLog struct { Timestamp time.Time `json:"_timestamp"` Task models.Task `json:"task"` } err := json.Unmarshal(msg.Payload, &desiredLog) if err != nil { panic(err) } registerDesired(desiredLog.Task.Guid, desiredLog.Timestamp) }) _, err = natsClient.Subscribe("error.>", func(msg *yagnats.Message) { var errorLog struct { Timestamp time.Time `json:"_timestamp"` Error string `json:"error"` } err := json.Unmarshal(msg.Payload, &errorLog) if err != nil { panic(err) } registerError(msg.Subject+": "+errorLog.Error, errorLog.Timestamp) }) _, err = natsClient.Subscribe("fatal.>", func(msg *yagnats.Message) { var errorLog struct { Timestamp time.Time `json:"_timestamp"` Error string `json:"error"` } err := json.Unmarshal(msg.Payload, &errorLog) if err != nil { panic(err) } registerError(msg.Subject+": "+errorLog.Error, errorLog.Timestamp) }) executorIndexes := map[string]int{} _, err = natsClient.Subscribe("completed-task", func(msg *yagnats.Message) { defer func() { e := recover() if e != nil { logger.Error("RECOVERED PANIC:", e) } }() var task *models.Task err := json.Unmarshal(msg.Payload, &task) if err != nil { panic(err) } simulationLock.Lock() index, ok := executorIndexes[task.ExecutorID] if !ok { index = len(executorIndexes) + 1 executorIndexes[task.ExecutorID] = index } data, ok := taskTracker[task.Guid] if !ok { logger.Error("uknown.runonce.completed", task.Guid, "executor", task.ExecutorID) simulationLock.Unlock() return } data.CompletionTime = float64(time.Now().UnixNano()) / 1e9 logger.Info("runonce.completed", task.Guid, "executor", task.ExecutorID, "duration", data.CompletionTime-data.DesiredTime) data.ExecutorIndex = index data.NumCompletions++ simulationLock.Unlock() simulationWait.Done() }) if err != nil { panic(err) } err = natsClient.PublishWithReplyTo("stage", "completed-task", payload) if err != nil { panic(err) } cleanup.Register(func() { dt := time.Since(t) logger.Info("simulation.end", nTasks, "runtime", dt) simulationResult(dt) simulationErrors() }) simulationWait.Wait() }