func (reader *Reader) Close() error {
	reader.closing = true
	err := reader.namedPipe.Close()
	if err != nil {
		return err
	}
	return nil
}
Close closes the reader.
package ipcnotification
import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"os"
	"syscall"
)
type Notification struct {
	Version int         `json:"version"`
	Topic   string      `json:"topic"`
	Payload interface{} `json:"payload"`
}
func (notification *Notification) String() string {
	return fmt.Sprintf("[Version: %d, Topic: %s, Payload: %v]", notification.Version, notification.Topic, notification.Payload)
}
type Reader struct {
	notifications chan Notification
	closing       bool
	filePath      string
	namedPipe     *os.File
}
func NewReader(filepath string) (*Reader, error) {
	reader := &Reader{
		notifications: make(chan Notification),
		filePath:      filepath,
		namedPipe:     nil,
		closing:       false,
	}
	_, err := os.Stat(reader.filePath)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			log.Printf("Could not find named pipe '%s'. Creating new named pipe.", reader.filePath)
			err := syscall.Mkfifo(reader.filePath, 0600)
			if err != nil {
				return nil, fmt.Errorf("could not create a new named pipe '%s': %w", reader.filePath, err)
			}
		} else {
			return nil, fmt.Errorf("could not stat the named pipe '%s': %w", reader.filePath, err)
		}
	} else {
		log.Printf("Using existing named pipe '%s' for IPC notifications.", reader.filePath)
	}
	namedPipe, err := os.OpenFile(reader.filePath, os.O_RDWR, os.ModeNamedPipe)
	if err != nil {
		return nil, fmt.Errorf("could not open the named pipe in '%s': %w", reader.filePath, err)
	}
	reader.namedPipe = namedPipe
	go reader.read()
	return reader, nil
}
func (reader *Reader) read() {
	defer func() {
		err := reader.namedPipe.Close()
		if err != nil {
			log.Printf("Could not close named pipe: %s", err)
		}
	}()
	scanner := bufio.NewScanner(reader.namedPipe)
	for {
		if scanner.Scan() {
			notificationBytes := scanner.Bytes()
			notificationText := scanner.Text()
			if len(notificationBytes) >= 4096 {
				log.Printf("IPC notification dropped: longer than 4095 byte (%d byte).\n", len(notificationBytes))
				continue
			}
			notification := Notification{}
			err := json.Unmarshal(notificationBytes, &notification)
			if err != nil {
				log.Printf("IPC notification dropped: could not unmarshal as JSON '%s': %s.\n", notificationText, err)
				continue
			}
			reader.notifications <- notification
		} else {
			err := scanner.Err()
			if err == nil {
				break
			}
			if errors.Is(err, os.ErrClosed) && reader.closing {
				break
			}
			log.Printf("Could not read from named pipe %s", err)
			break
		}
	}
}
func (reader *Reader) Notifications() chan Notification {
	return reader.notifications
}