// Run executes the RPC call(s). It is synchronous - it will wait for all requestrs // to return or timeout. func (r *RPCCall) Run() error { // Send all the RPC calls in go routines. var sendTime time.Time if showRunTimes { sendTime = time.Now() } err := r.send() if err != nil { msg := fmt.Sprintf("Error starting RPC calls.") log.Error(msg) return errors.New(msg) } // Collect responses via the "r.results" channel. if r.processes > 0 { var timedout bool timeout := common.TimeoutChan(rpcTimeout) for !timedout { select { case answer := <-r.results: r.adpList[answer.adapter.ID] = answer r.processes-- if answer.err != nil { r.errs = append(r.errs, answer.err) log.Errorf("RPC call to: %q failed - %s", answer.adapter.ID, answer.err) break } // log.Debug("Answer: %s", answer.response) r.process(answer.response) case timedout = <-timeout: } if r.processes == 0 { break } } if timedout { for k, v := range r.adpList { if v == nil { log.Errorf("Adapter: %q timed out", k) } } } } if showRunTimes { log.Info("RPC Call: %q took: %s", r.service, time.Since(sendTime)) } return nil }
func (sd *ServicesData) Refresh() error { serviceCall := "Service.All" log.Info("Refreshing Services List...") creq := structs.NServiceRequest{ City: "", } // log.Debug("%+v\n", creq) var responses []interface{} for range adapters.Adapters { responses = append(responses, &structs.NServicesResponse{}) } done, listIF, processes, _ := callRPCs(serviceCall, &creq, responses) log.Debug(" Processes: %d", processes) if processes > 0 { sd.Lock() defer sd.Unlock() timeout := common.TimeoutChan(rpcTimeout) timedout := false for !timedout { select { case answer := <-done: processes-- if answer.Error != nil { log.Errorf("RPC call %q failed: %s\n", serviceCall, answer.Error) break } r := answer.Reply.(*structs.NServicesResponse) listIF[r.IFID].replied = true log.Debug("\tMerging Services list for %q", r.IFID) sd.merge(&r.Services) case timedout = <-timeout: } if processes <= 0 { break } } failed := false for k, v := range listIF { switch { case v.sent && !v.replied: log.Errorf("RPC call %q to: %s timed out.", serviceCall, k) failed = true case !v.sent: log.Errorf("Engine and Adapter configs are out of synch - received reply from: %s", k) failed = true } } if failed { log.Error("Service List refresh FAILED!") } else { log.Info("Service List refresh complete...") } } // log.Debug(spew.Sdump(sd)) return nil }