С помощью xml.Marshal происходит гонка данных

#go

#Вперед

Вопрос:

Я получаю сообщение о странной скачке данных при использовании xml.Marshal в структуре. Я на 99% уверен, что я не отправляю ту же переменную или что-то в этом роде — вместо этого я получаю периодические ошибки, в которых функция marshal считает, что это вызывает скачок данных.

Вот код (немного упрощенный, но все функциональные элементы присутствуют):

 // this is run prior to any calls being sent to the below functions
func Setup() (descriptor *serviceDescriptor) {
    descriptor = new(serviceDescriptor)

    wpChan := make(chan *Call)
    for i := 1; i < 100; i   {
        go serviceWorker(wpChan)
    }
    descriptor.wpChan = wpChan

    return
}   

// called externally to initiate a call
func (s *serviceDescriptor) Add(c *Call) {
    go s.makeCall(c)
}

// sends a call to the worker pool set up in the Setup() function
func (s *serviceDescriptor) makeCall(c *Call) {

    cw := new(callwrapper)
    cw.internal = new(etFullCall)
    cw.internal.Calldata = c

    /// this is a channel that the next function listens to
    s.wpChan <- ct

   // the result is sent back on a channel and processed here
}

// this is a function 
func worker(wpChan chan *callwrapper) {
    for cw := range wpChan {
        v := new(Result)

        // this is where the data race occurs.    
        byt, err := xml.Marshal(cw.internal)

        // do stuff with the result down here

    }

}
  

Вот ошибка:

 WARNING: DATA RACE
Write by goroutine 115:
  runtime.copy()
      /usr/lib/go/src/pkg/runtime/slice.c:120  0x0
  encoding/xml.(*parentStack).push()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:901  0x2bd
  encoding/xml.(*printer).marshalStruct()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:819  0x58c
  encoding/xml.(*printer).marshalValue()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:524  0x12a8
  encoding/xml.(*Encoder).Encode()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:153  0x83
  encoding/xml.Marshal()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:72  0x9d
  exacttarget.serviceWorker()
      /service.go:94  0x20e

Previous write by goroutine 114:
  runtime.copy()
      /usr/lib/go/src/pkg/runtime/slice.c:120  0x0
  encoding/xml.(*parentStack).push()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:901  0x2bd
  encoding/xml.(*printer).marshalStruct()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:819  0x58c
  encoding/xml.(*printer).marshalValue()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:524  0x12a8
  encoding/xml.(*Encoder).Encode()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:153  0x83
  encoding/xml.Marshal()
      /usr/lib/go/src/pkg/encoding/xml/marshal.go:72  0x9d
  exacttarget.serviceWorker()
     /service.go:94  0x20e

Goroutine 115 (running) created at:
  service.Setup()
     /service.go:39  0x112
  /src.processSingleUser()
      /main_test.go:405  0xdf
  /src.testAddLists()
      /main_test.go:306  0x1f2

Goroutine 114 (running) created at:
  service.Setup()
     /service.go:39  0x112
  /src.processSingleUser()
      /main_test.go:405  0xdf
  src.testAddLists()
      /main_test.go:306  0x1f2
  

Комментарии:

1. Давайте поиграем в «Найди php-программиста»! что-то в пропущенном коде должно быть причиной гонки.

2. @OneOfOne это, конечно, возможно. Мы приложили усилия, чтобы убедиться, что каждая операция является идемпотентной. Каждая подпрограмма создает новую структуру вызова, и с ними не выполняется никаких дальнейших манипуляций. Пожалуйста, дайте мне знать, если вам понадобится дополнительная информация, чтобы помочь в отладке этого.

3. читая эту трассировку стека и код, стоящий за ней, я на 90% уверен, что это ложноположительный результат. И если бы это был истинный положительный результат, вы не смогли бы это исправить без изменения slice.c или переопределения кодировщика xml.

4. можете ли вы попытаться воспроизвести небольшой тестовый пример?

5. Что касается фактической гонки, она не похожа на гонку из encoding/xml . Более вероятно, что вы передаете один указатель на несколько xml.Marshal ‘s. Без полного кода мало что может помочь.