【发布时间】:2020-09-04 11:55:43
【问题描述】:
我是从golang开始的,出于性能原因,我需要修改一些方法:
我有下一个方法:
func (fs *ServiceImpl) GetContext(Item *models.Item, CallerID *int64, txn newrelic.Transaction) (models.Context, error) {
var context models.Context
//Resource1
item := Item
resource1, err := getResource1(fs, Item, txn)
if err != nil {
logger.Error("error", err)
}
context.Item = item
context.Resource1 = resource1
//Resource2
resource2, err := getResource2(fs, Item, CallerID, txn)
if err != nil {
logger.Error("error", err)
}
context.Resource2 = resource2
//Resource3
resource3, err := getResource3(fs, Item, txn)
if err != nil {
logger.Error("error", err)
}
context.Resource3 = resource3
return context, err
}
那么我有:
func getResource1(fs *ServiceImpl, Item *models.Item, txn Transaction) (*models.Resource1, error) {
r1 := models.Resource1{}
c1, err := fs.C1Provider.GetC1(Item.C1ID, txn)
if err == nil {
c1.C1s = &c1.PathFromRoot
} else {
logger.Errorf("error", err)
}
u1, err := fs.U1Provider.GetU1(Item.U1ID, txn)
if err == nil {
r1.StoreType = &u1.U1Type
r1.ReputationLevel = &u1.Reputation.LevelID
} else {
logger.Errorf("error", err)
}
return &r1, err
}
func getResource2(fs *ServiceImpl, Item *models.Item, CallerID *int64, txn Transaction) ([]models.Resource2, error) {
var r2 []models.Resource2
ri2, err := getAux1R1(fs, Item, CallerID, txn)
r2 = append(experiments, *ri2)
return r2, err
}
func getAux1R2(fs *ServiceImpl, Item *models.Item, CallerID *int64, txn Transaction) (*models.Resource2, error) {
if CallerID == nil {
return &models.Resource2{Name: "XXX", Variant: "DEFAULT"}, nil
}
seed := strconv.FormatInt(*CallerID, 10)
param := models.Resource2RequestParam{
Resource2Name: "XXX",
Seed: seed
}
r2, err := getAux2R2(fs, param, txn)
return r2, err
}
func getAux2R2(fs *ServiceImpl, param models.Resource2RequestParam, txn Transaction) (*models.Resource2, error) {
exp, err := fs.Resource2Service.GetResource2Configuration(param.Resource2Name, param.Seed)
r2 := &models.Resource2{
Name: exp.Resource2Name(),
Variant: exp.VariantID(),
}
return r2, err
}
最后:
func getResource3(fs *ServiceImpl, Item *models.Item, txn Transaction) (*models.Resource3, error) {
var r3 *models.Resource3
if !utils.Contains(text.ENABLE_XXX, Item.SiID) {
return r3, nil
}
pay, err := getAux1R3(fs, Item, txn)
if err == nil {
switch Item.SiID {
case text.P_X:
r3 = pay.SetForX()
case text.P_Y:
r3 = pay.SetForY()
case text.P_Z:
r3 = pay.SetForZ()
}
}
return r3, err
}
func getAux1R3(fs *ServiceImpl, Item *models.Item, txn Transaction) (*models.Resource3, error) {
result, err := fs.P1Provider.GetP1Options(Item.ID, txn)
if err != nil {
logger.Errorf("error", err)
return nil, err
}
return result, nil
}
这些方法是api调用,需要相当长的时间:
c1, err := fs.C1Provider.GetC1(Item.C1ID, txn)
exp, err := fs.Resource2Service.GetResource2Configuration(param.Resource2Name, param.Seed)
result, err := fs.P1Provider.GetP1Options(Item.ID, txn)
我不关心调用的顺序,但GetContext方法必须在最后完成。
我必须如何实现带有通道的 goroutine 才能很好地执行此调用?
提前致谢!
【问题讨论】:
-
您已经共享数据和一个
txn变量传递给所有这些函数。txn是否能够处理并发呼叫?共享数据对于并发访问是安全的,即它是只读的,还是每个函数修改它的独占部分?如果没有,您可能无法在此处使用 goroutine。