Доброго времени суток.
Появилась проблема с параллельностью на го.
Хочу, чтобы мой валидатор валидировал данные параллельно с помощью каналов:
валидатор должен обойти каждую структуру в цикле и обработать её с помощью горутины.
Уже три дня пытаюсь обойти проблемы связанные с тем, что данный цикл не дорабатывает до конца, что в итоге приводит к тому, что не каждая структура обрабатывается. С каналами не очень дружу, к сожалению, т.к. в го сам недавно. Очень прошу помочь. Код ниже:
Тип структуры и её полей(всё крайне просто) :
type Struct struct {
Name string
Fields []Field
}
type Field struct {
Name, Type string
}
Код обработки структур:
package validator
import (
"errors"
c "github.com/victorolegovich/storage_generator/collection"
p "github.com/victorolegovich/storage_generator/parser"
"github.com/victorolegovich/storage_generator/types"
)
type errorType struct {
section string
error string
}
type crossingChannels struct {
ErrorChan chan errorType
RequiredStructChan chan string
}
func StructsValidation(Structs []c.Struct) error {
var errorText string
errs := map[string]string{}
channels := crossingChannels{
ErrorChan: make(chan errorType),
RequiredStructChan: make(chan string),
}
structsNames := ExtractStructsNames(Structs)
for i := 0; i < len(Structs); i++ {
go StructValidation(Structs[i], channels)
result := <-channels.RequiredStructChan
if !StructExist(structsNames, result) {
errs[fieldsSection] += result + ": field type is not exist in this file\n"
}
}
if len(errs) != 0 {
for section, s := range errs {
errorText += section + ":\n" + s
}
}
return errors.New(errorText)
}
func ExtractStructsNames(Structs []c.Struct) (Names []string) {
for _, Struct := range Structs {
Names = append(Names, Struct.Name)
}
return Names
}
func StructExist(StructsNames []string, StructName string) bool {
for _, SName := range StructsNames {
if SName == StructName {
return true
}
}
return false
}
func StructValidation(Struct c.Struct, channels crossingChannels) {
for _, Field := range Struct.Fields {
FieldValidation(Field, channels)
}
}
func FieldValidation(Field c.Field, channels crossingChannels) {
typeVerify(Field, channels)
}
func typeVerify(Field c.Field, channels crossingChannels) {
ftype := Field.Type
if result, typename := isArray(ftype); result {
if !types.IsSimpleType(typename) {
channels.RequiredStructChan <- typename
}
return
}
if result, maptype := isMap(ftype); result {
if !types.IsSimpleType(maptype.key) {
channels.RequiredStructChan <- maptype.key
}
if !types.IsSimpleType(maptype.value) {
channels.RequiredStructChan <- maptype.value
}
return
}
if !types.IsSimpleType(ftype) {
if ftype != c.ComplicatedType {
channels.RequiredStructChan <- ftype
return
}
channels.ErrorChan <- errorType{
section: typesSection,
error: ftype + " is complicated type",
}
}
return
}
P.S. Пробовал вэйт группы, мьютексы, буферизировал каналы - ничто из этого у меня не получилось сделать правильно(