~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
68 lines · 1.2 KB Raw History
package notify

import (
	"context"
	"net"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	EnvSocket = "NOTIFY_SOCKET"

	EnvWatchdogUSec = "WATCHDOG_USEC"
)

func Ready() error { return send("READY=1") }

func Watchdog() error { return send("WATCHDOG=1") }

func send(state string) error {
	addr := os.Getenv(EnvSocket)
	if addr == "" {
		return nil
	}
	c, err := net.Dial("unixgram", socketName(addr))
	if err != nil {
		return err
	}
	defer c.Close()
	_, err = c.Write([]byte(state))
	return err
}

func socketName(addr string) string {
	if strings.HasPrefix(addr, "@") {
		return "\x00" + addr[1:]
	}
	return addr
}

func WatchdogInterval() time.Duration {
	usec, err := strconv.ParseInt(strings.TrimSpace(os.Getenv(EnvWatchdogUSec)), 10, 64)
	if err != nil || usec <= 0 {
		return 0
	}
	return time.Duration(usec) * time.Microsecond
}

func KeepAlive(ctx context.Context, onError func(error)) {
	interval := WatchdogInterval()
	if interval <= 0 || os.Getenv(EnvSocket) == "" {
		return
	}
	tick := time.NewTicker(interval / 2)
	defer tick.Stop()
	for {
		select {
		case <-ctx.Done():
			return
		case <-tick.C:
			if err := Watchdog(); err != nil && onError != nil {
				onError(err)
			}
		}
	}
}