func packResponse(returnCode int, returnMessage string, code_list []int, message_list, district_list []string, data interface{}) []byte { resp := sjson.New() resp.Set("returnCode", returnCode) resp.Set("returnMessage", returnMessage) resp.Set("data", data) resp.Set("codes", code_list) resp.Set("msgs", message_list) resp.Set("districts", district_list) resp_str, err := resp.EncodePretty() if err != nil { log.Error("EncodePretty error") resp_str = []byte("EncodePretty error") } return resp_str }
func getCvmList(w http.ResponseWriter, req *http.Request) { // parse parameters app_id, owner_uin, district := parseParams(req) var resp_str []byte if app_id < 0 { // fail log.Error("invalid app_id : ", app_id) resp_str = packResponse(cvmcode.PARAM_ERR, "param error", nil, nil, nil, nil) w.Write(resp_str) return } log.Infof("get req -> app_id : %d owner_uin : %s district : %s\n", app_id, owner_uin, district) // expect cvm list code_list, message_list, district_list, device_list := processGetCvmList(app_id, owner_uin, district) log.Info("final code_list => ", code_list) log.Info("final message_list => ", message_list) log.Info("final district_list => ", district_list) log.Info("final device_list => ", device_list) final_return_code := cvmcode.CGW_INTERFACE_ALL_FAIL final_return_msg := "all cgw interface failed" // return ok if there are any interface returns ok for _, rt_code := range code_list { if rt_code == cvmcode.OK { final_return_code = cvmcode.OK final_return_msg = "ok" break } } device_num := len(device_list) cvms := sjson.New() cvms.Set("totalNum", device_num) cvms.Set("deviceList", device_list) // response resp_str = packResponse(final_return_code, final_return_msg, code_list, message_list, district_list, cvms) w.Write(resp_str) }
// return 4 slices // code message district devicelist func processGetCvmList(app_id int, owner_uin, district string) ([]int, []string, []string, []interface{}) { code_list := make([]int, 0) message_list := make([]string, 0) district_list := make([]string, 0) device_list := make([]interface{}, 0) // calling all the interfaces if district == "all" var interface_list []string switch district { case "gz": interface_list = []string{cgw_conf.Gz} case "sh": interface_list = []string{cgw_conf.Sh} case "hk": interface_list = []string{cgw_conf.Hk} case "ca": interface_list = []string{cgw_conf.Ca} case "all": interface_list = []string{cgw_conf.Gz, cgw_conf.Sh, cgw_conf.Hk, cgw_conf.Ca} default: log.Error("invalid district -> ", district) // return empty list return code_list, message_list, district_list, device_list } interface_num := len(interface_list) // wait for all the interface to return collect_ch := make(chan Resp1, interface_num) var wait_group sync.WaitGroup wait_group.Add(interface_num) // calling multiple interfaces concurrently for _, interface_name := range interface_list { // each with a single goroutine go func(interface_name string) { defer wait_group.Done() // get the first 1024 cvms start_idx := 0 end_idx := 1023 // for timeout control and result retrive ch := make(chan Resp0, 1) // POST request in goroutine // response should be written to ch go requestInterface(start_idx, end_idx, app_id, owner_uin, interface_name, ch) // no data resp1 := Resp1{ district: getDistrictNameFromInterface(interface_name), data: make([]interface{}, 0), } // expect response from ch total_cvm_num := dealCgwResponse(ch, &resp1) start_idx = end_idx + 1 end_idx = total_cvm_num - 1 // no more cvms if end_idx < start_idx { collect_ch <- resp1 return } // get the ramaining cvms in another goroutine go requestInterface(start_idx, end_idx, app_id, owner_uin, interface_name, ch) dealCgwResponse(ch, &resp1) // response anyway collect_ch <- resp1 }(interface_name) } // wait for all the interface to return wait_group.Wait() collect_result_done := false // iterate until all data are collected for collect_result_done == false { select { case final_result := <-collect_ch: log.Info("collect -> ", final_result) // collect cvms in data for _, cvm := range final_result.data { device_list = append(device_list, cvm) } // collect code & message & district code_list = append(code_list, final_result.code) message_list = append(message_list, final_result.message) district_list = append(district_list, final_result.district) default: // done collect_result_done = true } } return code_list, message_list, district_list, device_list }