Files
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

71 lines
2.5 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"time"
"github.com/itworx/pulse/internal/agentstore"
"github.com/itworx/pulse/internal/database"
"github.com/itworx/pulse/internal/runtimeconfig"
"github.com/jackc/pgx/v5/pgxpool"
)
const (
// storeConnectTimeout bounds the start-up reachability check. The healthcheck
// contract wants the first heartbeat written after the database is reachable, so
// this must stay far below the 45 second staleness threshold.
storeConnectTimeout = 5 * time.Second
// agentPoolMaxConns keeps the agent's footprint on the shared database small: it
// issues one small write per capability per interval and never reads.
agentPoolMaxConns = 2
)
// errStoreNotLinked is returned by every write while no snapshot store implementation
// is compiled into this binary. It is deliberately an error on the write path rather
// than a silent drop: the reader turns a missing snapshot into Unknown, and the agent
// log states plainly why nothing arrives.
var errStoreNotLinked = errors.New("no agent snapshot store is linked into this build")
// openStore connects to PostgreSQL and returns the narrow Writer the agent publishes
// through, plus a close function.
//
// The agent depends on the agentstore.Writer interface only; the concrete PostgreSQL
// store owns migration 0016 and the agent_snapshots table.
func openStore(ctx context.Context, config runtimeconfig.AgentConfig) (agentstore.Writer, func(), error) {
pool, err := database.NewPool(ctx, database.Config{
URL: config.DatabaseURL,
MaxConns: agentPoolMaxConns,
MinConns: 1,
})
if err != nil {
// Never wrap the URL itself into the error: it carries the database password.
return nil, nil, errors.New("agent database pool could not be created")
}
reachable, cancel := context.WithTimeout(ctx, storeConnectTimeout)
defer cancel()
if err := database.Ping(reachable, pool); err != nil {
pool.Close()
return nil, nil, fmt.Errorf("agent database is unreachable: %w", err)
}
writer, err := newSnapshotWriter(pool)
if err != nil {
pool.Close()
return nil, nil, err
}
return writer, pool.Close, nil
}
// newSnapshotWriter builds the store the agent writes through. A nil pool would make
// every publish fail silently at the driver, so it is refused here instead: the agent
// must either have a real store or fail to start.
func newSnapshotWriter(pool *pgxpool.Pool) (agentstore.Writer, error) {
if pool == nil {
return nil, errStoreNotLinked
}
return agentstore.PostgresStore{Pool: pool}, nil
}
var _ agentstore.Writer = agentstore.PostgresStore{}