укладка данных из go подпрограмм - PullRequest
1 голос
/ 22 апреля 2020

Я изучаю go lang, и я хотел бы создать приложение go для достижения следующих целей:

  1. получение данных из удаленного журнала
  2. анализ какая-то ошибка предупреждения
  3. периодически отправляет HTTP-запрос на URL-адрес, сообщающий, что все в порядке, или отправляет предупреждение и ошибку.

Я читал о параллелизме, параллелизме и каналы, но я не уверен, как я должен передать данные из моей процедуры регистрации в другую подпрограмму с таймером, чтобы сделать запрос. Должен ли я объявить фрагмент в другой подпрограмме, чтобы получить все сообщения, и в конце таймер перебирает его?

в настоящее время мой код выглядит следующим образом:

package main

import (
    "fmt"
    "log"
    "strings"

    "gopkg.in/mcuadros/go-syslog.v2"
)

func strigAnalyze(str string){
/*analyse the contents of the log message and do something*/
}

func main() {

    channel := make(syslog.LogPartsChannel)
    handler := syslog.NewChannelHandler(channel)
    server := syslog.NewServer()
    server.SetFormat(syslog.RFC3164)
    server.SetHandler(handler)
    server.ListenUDP("0.0.0.0:8888")
    server.ListenTCP("0.0.0.0:8888")

    server.Boot()

    go func(channel syslog.LogPartsChannel) { 

        for logParts := range channel {
            content := logParts["content"]
            fmt.Println("logparts", logParts)
            string := fmt.Sprintf("%v", content)
            strigAnalyze(str) 
        }
    }(channel)
    server.Wait()
}

1 Ответ

1 голос
/ 22 апреля 2020

Должен ли я объявить срез в другой подпрограмме для получения всех сообщений и в конце перебрать таймер по нему?

Это один из наиболее распространенных шаблонов в 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
      }
   }
}()

Также в зависимости от того, как вы используете данные, может иметь смысл использовать здесь настоящий буфер вместо слайса.

...