func (s *Service) serveTCP(listener net.Listener) { defer s.wg.Done() for { select { case <-s.stop: return default: } if conn, err := listener.Accept(); err != nil { log.Error("Failed to accept TCP conn", "err", err) } else { s.wg.Add(1) go func(conn net.Conn) { defer s.wg.Done() defer conn.Close() if s.currentMsg != "" { if _, err := conn.Write([]byte(s.currentMsg + "\n")); err != nil { log.Error("Failed to write to TCP conn", "conn", conn, "err", err) } } }(conn) } } }
func CSVField(fieldIndex int, source DataSource) MessageBuilder { c := make(chan []string) go func() { for { reader := csv.NewReader(strings.NewReader(<-source)) reader.TrimLeadingSpace = true reader.FieldsPerRecord = -1 var values []string // Ignore first line - comment reader.Read() for { if record, err := reader.Read(); err == io.EOF { break } else if err != nil { log.Error("Error reading CSV data", "err", err) } else if len(record) <= fieldIndex { log.Error("Error reading CSV data: index out of bounds", "# fields in record", record, "index", fieldIndex) } else { values = append(values, record[fieldIndex]) } } if len(values) == 0 { log.Error("Didn't get any values from CSV") } else { log.Info("Read CSV data", "num values", len(values)) c <- values } } }() return c }
func FileWatcher(filename string) (DataSource, error) { // Make sure we can open the file, even though it might go away later if f, err := os.Open(filename); err != nil { f.Close() return nil, err } else { f.Close() } c := make(chan string) go func() { var fileContents []byte for { if f, err := os.Open(filename); err == nil { defer f.Close() // Read and send if contents have changed if newContents, err := ioutil.ReadAll(f); err != nil { log.Error("Failed to read file", "err", err) } else if bytes.Compare(newContents, fileContents) != 0 { fileContents = newContents c <- string(fileContents) } } time.Sleep(3 * time.Second) } }() return c, nil }
func (s *Service) Stop() { defer s.wg.Wait() log.Info("Stopping service") close(s.stop) // TCPListener might still be blocked, so open a conn to it ourselves // to free it up. if conn, err := net.DialTCP("tcp", nil, s.addr); err != nil { log.Error("Failed to close down TCP listener", "err", err) } else { conn.Close() log.Info("Shut down TCP listener") } }
func (s *Service) start() { defer s.wg.Done() var bonj *bonjour.Server defer func(b **bonjour.Server) { s.stopBonjour(*b) }(&bonj) for { select { case msg := <-s.messages: if msg != s.currentMsg { s.currentMsg = msg s.stopBonjour(bonj) bonj = nil if msg != "" { log.Info("Registering service", "name", msg, "host", s.host, "port", s.port) var err error bonj, err = bonjour.RegisterProxy( msg, "_afpovertcp._tcp", "local", s.port, s.host, s.host, nil, nil) if err != nil || bonj == nil { log.Error("Failed to register service with bonjour", "err", err) bonj = nil } } } case <-s.stop: log.Info("Ending bonjour-updating routine") return } } }