V
V
VictorOlegovich2019-10-15 21:40:05
go
VictorOlegovich, 2019-10-15 21:40:05

What is the correct way to handle pipes in go?

Good day.
There was a problem with parallelism in Go.
I want my validator to validate the data in parallel using channels: the
validator should loop through each structure and process it using a goroutine.
For three days I have been trying to get around the problems associated with the fact that this cycle does not finish to the end, which ultimately leads to the fact that not every structure is processed. Unfortunately, I am not very friendly with channels. in th myself recently. I beg you to help me. The code is below:
The type of the structure and its fields (everything is extremely simple):

type Struct struct {
  Name   string
  Fields []Field
}

type Field struct {
  Name, Type string
}

Structure processing code:
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
}

PS I tried weight groups, mutexes, buffered channels - none of this I managed to do correctly (

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
index0h, 2019-10-17
@index0h

If I understand your task correctly, making a validator on goroutines is not a good idea, you will only lose performance, and add crap to yourself.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question