Я новичок в каналах GoLang, но он работает не так, как я ожидал.
У меня есть функция, для которой я хочу вызвать 3 отдельные горутины, а затем дождаться их завершения. Если я получаю сообщение об ошибке, я пытаюсь поместить его в CHAN, а затем обработать ошибку после завершения wg.Wait()
.
К сожалению, при просмотре результатов CHAN он зависает. Я предполагаю, что он все еще ждет заполнения CHAN, но не все горутины будут вызывать ошибки.
Как лучше всего справиться с зацикливанием каналов, которые не всегда заполняются? Я также знаю, что здесь мне необязательно использовать CHAN, но я хотел убедиться, что я их понял.
Ниже мой код.
func createWorkoutPlanForUserPreconditionCheck(planID, userID, transactionID *string) (*sharedstructs.Plan, *sharedstructs.User, *sharedstructs.Profile, error) {
if planID == nil || userID == nil || transactionID == nil {
return nil, nil, nil, sharedstructs.InvalidData{Msg: "Cannot pass in Nil Parameters"}
}
plan := sharedstructs.Plan{}
user := sharedstructs.User{}
profile := sharedstructs.Profile{}
//myError := sharedstructs.InvalidData{}
ch := make(chan sharedstructs.InvalidData, 3)
var wg sync.WaitGroup
wg.Add(3)
//Get the Plan from the Plan ID
go func() {
defer wg.Done()
returnedPlan, readError := readPlan(*planID)
if readError != nil || returnedPlan == nil {
ch <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
plan = *returnedPlan
}
}()
//Get the User
go func() {
defer wg.Done()
returnedUser, getUserError := userdomain.GetUserByID(*userID, *transactionID)
if getUserError != nil || &returnedUser == nil {
ch <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
user = returnedUser
}
}()
//Get the Profile
go func() {
defer wg.Done()
readProfile, getProfileError := profiledomain.GetProfile(*userID, *transactionID)
if getProfileError != nil || readProfile == nil {
ch <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
profile = *readProfile
}
}()
wg.Wait()
////"Hangs Here" - PUT MY ERROR HANDLING LOGIC HERE
for err := range ch {
fmt.Println(err.Error())
}
return &plan, &user, &profile, nil
}