~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
70 lines · 1.4 KB Raw History
package postgresctl

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/fsnotify/fsnotify"

	"github.com/johnandersen777/socialweb-computer-kcp/api/v1alpha1"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/fswatch"
)

const (
	PidFileName = "postmaster.pid"

	pidStatusLine = 7

	pidStatusReady = "ready"
)

func (h *Host) PidFile(o v1alpha1.Postgres) string {
	return filepath.Join(h.DataDir(o), PidFileName)
}

func (h *Host) Accepting(o v1alpha1.Postgres) bool {
	raw, err := os.ReadFile(h.PidFile(o))
	if err != nil {
		return false
	}
	lines := strings.Split(string(raw), "\n")
	return len(lines) > pidStatusLine && strings.TrimSpace(lines[pidStatusLine]) == pidStatusReady
}

func (h *Host) PidChanges(ctx context.Context, o v1alpha1.Postgres) (<-chan struct{}, error) {
	file := filepath.Clean(h.PidFile(o))
	w, err := fswatch.Shared().Subscribe(filepath.Dir(file))
	if err != nil {
		return nil, fmt.Errorf("postgresctl: watching %s: %w", filepath.Dir(file), err)
	}
	out := make(chan struct{}, 1)
	go func() {
		defer close(out)
		defer w.Close()
		for {
			select {
			case <-ctx.Done():
				return
			case ev, ok := <-w.Events():
				if !ok {
					return
				}
				if filepath.Clean(ev.Name) != file || ev.Op == fsnotify.Chmod {
					continue
				}
				select {
				case out <- struct{}{}:
				default:
				}
			case _, ok := <-w.Errors():
				if !ok {
					return
				}
			}
		}
	}()
	return out, nil
}