Service struct {
dao *dao.Dao
mu *sync.Mutex
ctx context.Context
}
У структура есть метод, который вызывается при работе 10+ горутин:
func (s *Service) getMetadataInstant(spec int, hash string) *metadata.Instant {
s.mu.Lock()
defer s.mu.Unlock()
metadataInstant, ok := metadata.RuntimeMetadata[spec]
if !ok {
raw := s.dao.RuntimeVersionRaw(spec)
if raw.Raw == "" {
raw.Raw = s.regCodecMetadata(hash)
}
metadataInstant = metadata.Process(raw) //тут race condition,
// metadata.Process(raw) пишет в глобальную мапу в пакете metadata
}
return metadataInstant
}
Не смотря на то, что я блокирую мютекс, я получил в коде race condition. Такого быть не должно, если мютекс заблокирован, или я неправильно понимаю суть мютекса?
Возможно у вас в другом месте идет работа с этой же map, либо у вас есть копия этого сервиса
возможно вам лок нужно перенести в место где map меняется
Спасибо, но в коде 1 сервис только. и он запускает пул горутин с помощью panjf2000/ants/v2, которые работают и в какой-то момент дёргают эту функцию, но копия сервиса одна.
Это конечно идеальный вариант, но там либа сторонняя, которая постоянно обновляется, можно конечно PR послать, наверное попробую, кстати, спасибо)
> metadata.Process(raw) пишет в глобальную мапу в пакете metadata а оно синхронизировано?
но я для этого мютекс использую, чтобы именно этот участок,где происходит запись, заблочить
еще вариант что вывоз функции process можно делать не в каждой горутине а только в одной, а остальные е б ей передавали данные через канал
Обсуждают сегодня