I'm pretty new in Go and need the answers to some of dilemmas while implementing small HTTP notifier than runs concurrently, sending message to the configured HTTP endpoint. For that purpose, I use the following structure:
type Notifier struct {
url string
waitingQueue *list.List
progress *list.List
errs chan NotificationError
active sync.WaitGroup
mu sync.Mutex
}
Here is the notify
method:
func (hn *Notifier) Notify(message string) {
if hn.ProcessingCount() < hn.config.MaxActiveRequestsCount() && hn.checkIfOlderThanOldestWaiting(time.Now().Unix()) {
element := hn.addToProgressQueue(message)
hn.active.Add(1)
go hn.sendNotification(element)
} else {
hn.waitingQueue.PushBack(QueueItem{message, time.Now().UnixNano()})
}
}
And addToInProgressQueue
:
func (hn *Notifier) addToProgressQueue(message string) *list.Element {
hn.mu.Lock()
defer hn.mu.Unlock()
queueItem := QueueItem{message, time.Now().UnixNano()}
element := hn.progress.PushBack(queueItem)
return element
}
I guess this won't work as expected for concurrent reads/writes of queue? Is it enought to use RWMutex instead of Mutex to ensure the locks are working properly?
The code of
ProcessingCount
func (hn *Notifier) ProcessingCount() int {
hn.mu.Lock()
defer hn.mu.Unlock()
return hn.inProgress.Len()
}
Can there be a data race here?
Also, if you have some good resources on data race examples in Golang, it would be well appreciated.
Thanks in advance