Должен ли я объявить срез в другой подпрограмме для получения всех сообщений и в конце перебрать таймер по нему?
Это один из наиболее распространенных шаблонов в go. Пример, который вы описываете, иногда называют « подпрограммой монитора ». Он защищает буфер журналов и, поскольку он «владеет» ими, вы знаете, что они защищены от одновременного доступа.
Данные передаются по каналу, и поставщик данных журнала будет полностью отделен от того, как отправитель использует его, все, что ему нужно сделать, это отправить по каналу. Если канал не буферизован, то ваш производитель будет блокировать, пока получатель не сможет обработать. Если вам нужно поддерживать высокую производительность производителя, вы можете буферизовать канал или shed send , который будет выглядеть следующим образом:
select {
case logChan <- log:
...
default:
// chan is full shedding data.
}
Этот шаблон также очень хорошо подходит для "receive" l oop, что for...selects
по входному каналу, таймеру и некоторому виду done / context. Следующее не является рабочим примером, и в нем отсутствуют отмена и лог c, но оно показывает, как вы можете ... выбирать по нескольким каналам (одним из которых является ваш таймер / пульс):
logChan := make(chan string)
go func() {
var logBuf []string
t := time.NewTimer(time.Second * 5)
for {
select {
log, ok := <-logChan:
if !ok { return }
logBuf = append(logBuf, log)
<-t.C:
// timer up
// flush logs
// reset slice
}
}
}()
Также в зависимости от того, как вы используете данные, может иметь смысл использовать здесь настоящий буфер вместо слайса.