Help us shape the future of Go! Take the 2026 Go Developer Survey

agent

package
v0.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package agent is foony-sync: the customer-run Database Sync agent. It holds the customer's database credentials AND its live-query definitions locally (neither ever reaches foony), captures row changes over logical replication, recomputes the queries, and publishes the resulting docs to the app's reserved db: channels. The only inbound traffic it acts on is a warm request naming a channel. See https://foony.io/docs/database-sync.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run

func Run(ctx context.Context, cfg Config) error

Run starts the agent and blocks until ctx ends or startup fails in a way retrying cannot fix (bad config, bad credentials, unreachable database).

Types

type Config

type Config struct {
	// FoonyURL is the realtime data-plane base URL (https://realtime.foony.io).
	FoonyURL string
	// AgentKey is the source credential from the dashboard (appSlug.keyId:secret).
	AgentKey string
	// DatabaseURL is the customer Postgres DSN. The agent adds
	// replication=database itself for the WAL connection.
	DatabaseURL string
	// ConfigPath is the local definitions file (foony-sync.json).
	ConfigPath string
	// Version is the agent build version, reported on heartbeats.
	Version string
	Logger  *slog.Logger
}

Config is everything foony-sync needs: where foony is, the source credential, the customer database, and the local definitions file.

type FileConfig

type FileConfig struct {
	Queries []spec.Query `json:"queries"`
	// StatementTimeoutMs pins every query the agent runs (default 5000).
	StatementTimeoutMs int `json:"statementTimeoutMs,omitempty"`
	// WalRetentionCapBytes is the safety valve: past this much retained WAL
	// the agent recycles its replication slot (drop, re-attach, recompute
	// every live doc) rather than risk filling the database's disk. Bulk
	// writes on a large table can cross it in under a minute, so raise it for
	// a planned migration instead of disabling it (default 4 GiB; 0 keeps the
	// default, -1 disables).
	WalRetentionCapBytes int64 `json:"walRetentionCapBytes,omitempty"`
}

FileConfig is the agent's local config file (foony-sync.json): the live queries plus the two protect-my-database knobs. Definitions live here, next to the code that owns the schema, and never leave the machine; the agent reports only name and table summaries to the dashboard.

func LoadConfig

func LoadConfig(path string) (FileConfig, error)

LoadConfig reads and validates the agent config file. Every query is checked with the same rules the docs describe, so a typo fails fast at startup with a message naming the query.

type FoonyClient

type FoonyClient struct {
	// contains filtered or unexported fields
}

FoonyClient talks to foony for the agent: the dbsync control endpoints (heartbeats and live-doc listing) over plain REST, and doc publishes through the realtime SDK's Rest client, all authenticated with the source's api key.

func NewFoonyClient

func NewFoonyClient(baseURL, agentKey string) (*FoonyClient, error)

NewFoonyClient parses the agent key (appSlug.keyId:secret) into Basic credentials for baseURL.

func (*FoonyClient) AgentKey

func (client *FoonyClient) AgentKey() string

AgentKey returns the full credential (appSlug.keyId:secret) for the WebSocket handshake, which authenticates with the key directly: key auth is what opens the reserved dbsync: namespace.

func (*FoonyClient) KeyID

func (client *FoonyClient) KeyID() string

KeyID returns the public key id of the agent credential, the stable local identity the replication slot name derives from.

func (*FoonyClient) LiveDocs

func (client *FoonyClient) LiveDocs(ctx context.Context) ([]string, bool, error)

LiveDocs lists the db: channels that currently have subscribers, gathered from the edge fleet. The bool reports whether the view is complete; a truncated view must only extend the agent's live set, never shrink it.

func (*FoonyClient) PublishDoc

func (client *FoonyClient) PublishDoc(ctx context.Context, channel string, doc json.RawMessage) error

PublishDoc publishes a computed doc to its db: channel through the realtime SDK. The channel's built-in retained-last policy makes this both the live fan-out and the stored snapshot new subscribers replay.

func (*FoonyClient) SendHeartbeat

func (client *FoonyClient) SendHeartbeat(ctx context.Context, heartbeat Heartbeat) error

SendHeartbeat reports agent health to the source's dashboard row.

type Heartbeat

type Heartbeat struct {
	AgentVersion string              `json:"agentVersion"`
	State        string              `json:"state"`
	SlotLagBytes int64               `json:"slotLagBytes"`
	DirtyDepth   int64               `json:"dirtyDepth"`
	LastEventAt  *time.Time          `json:"lastEventAt,omitempty"`
	LastError    string              `json:"lastError,omitempty"`
	Queries      []spec.QuerySummary `json:"queries"`
}

Heartbeat is the body of POST /sync/heartbeat. Queries is a name-and-tables summary only: the definitions stay in the agent's local config.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL