client

package
v0.0.0-...-443440a Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package client provides job client operations for NATS JetStream.

Index

Constants

View Source
const (
	// DefaultPageSize is the default number of jobs per page.
	DefaultPageSize = 10
	// MaxPageSize is the maximum allowed page size.
	MaxPageSize = 100
)

Variables

This section is empty.

Functions

func ComputeAgentState

func ComputeAgentState(
	events []job.TimelineEvent,
) string

ComputeAgentState returns the current state from timeline events.

Types

type Client

type Client struct {

	// JSONMarshalFn is the function used to marshal JSON. Defaults to json.Marshal.
	// Exported for testing.
	JSONMarshalFn func(v any) ([]byte, error)
	// contains filtered or unexported fields
}

Client provides methods for publishing job requests and retrieving responses.

func New

func New(
	logger *slog.Logger,
	natsClient NATSClient,
	opts *Options,
) (*Client, error)

New creates a new jobs client using an existing NATS client.

func (*Client) CheckDrainFlag

func (c *Client) CheckDrainFlag(
	ctx context.Context,
	machineID string,
) bool

CheckDrainFlag returns true if the drain flag exists for the given identifier. Callers pass a machine ID (hex string, no sanitization needed).

func (*Client) ConsumeJobs

func (c *Client) ConsumeJobs(
	ctx context.Context,
	streamName, consumerName string,
	handler func(jetstream.Msg) error,
	opts *natsclient.ConsumeOptions,
) error

ConsumeJobs sets up message consumption for job processing.

func (*Client) CreateJob

func (c *Client) CreateJob(
	ctx context.Context,
	operationData map[string]interface{},
	targetHostname string,
) (*CreateJobResult, error)

CreateJob creates a new job from operation data and stores it in the KV bucket.

func (*Client) CreateOrUpdateConsumer

func (c *Client) CreateOrUpdateConsumer(
	ctx context.Context,
	streamName string,
	consumerConfig jetstream.ConsumerConfig,
) error

CreateOrUpdateConsumer creates or updates a JetStream consumer.

func (*Client) DeleteDrainFlag

func (c *Client) DeleteDrainFlag(
	ctx context.Context,
	machineID string,
) error

DeleteDrainFlag removes the drain flag for an agent from the state KV bucket. The agent detects this on heartbeat and resumes accepting jobs. Callers pass a machine ID (hex string, no sanitization needed).

func (*Client) DeleteJob

func (c *Client) DeleteJob(
	ctx context.Context,
	jobID string,
) error

DeleteJob deletes a job from the KV store by its ID.

func (*Client) GetAgent

func (c *Client) GetAgent(
	ctx context.Context,
	target string,
) (*job.AgentInfo, error)

GetAgent reads a single agent's registration from the KV registry. It tries a direct machine ID lookup first, then falls back to scanning all agents by hostname.

func (*Client) GetAgentTimeline

func (c *Client) GetAgentTimeline(
	ctx context.Context,
	hostname string,
) ([]job.TimelineEvent, error)

GetAgentTimeline returns sorted timeline events for a hostname.

func (*Client) GetJobData

func (c *Client) GetJobData(
	ctx context.Context,
	jobKey string,
) ([]byte, error)

GetJobData retrieves raw job data from the KV store.

func (*Client) GetJobStatus

func (c *Client) GetJobStatus(
	ctx context.Context,
	jobID string,
) (*job.QueuedJob, error)

GetJobStatus returns information about a specific job.

func (*Client) GetQueueSummary

func (c *Client) GetQueueSummary(
	ctx context.Context,
) (*job.QueueStats, error)

GetQueueSummary returns job queue statistics derived from KV key names only — no entry reads.

func (*Client) ListAgents

func (c *Client) ListAgents(
	ctx context.Context,
) ([]job.AgentInfo, error)

ListAgents reads the agent registry KV bucket and returns all registered agents. Agents register via heartbeat, so only live agents appear.

func (*Client) ListJobs

func (c *Client) ListJobs(
	ctx context.Context,
	statusFilter string,
	limit int,
	offset int,
) (*ListJobsResult, error)

ListJobs returns jobs filtered by status with server-side pagination. Uses a two-pass approach: Pass 1 derives status from key names only (fast), Pass 2 fetches full details for the paginated page only. Jobs are returned newest-first (reverse insertion order).

func (*Client) Modify

func (c *Client) Modify(
	ctx context.Context,
	target string,
	category string,
	operation job.OperationType,
	data any,
) (string, *job.Response, error)

Modify publishes a modify job to a single target and waits for the response.

func (*Client) ModifyBroadcast

func (c *Client) ModifyBroadcast(
	ctx context.Context,
	target string,
	category string,
	operation job.OperationType,
	data any,
) (string, map[string]*job.Response, error)

ModifyBroadcast publishes a modify job to a broadcast target and collects all responses.

func (*Client) Query

func (c *Client) Query(
	ctx context.Context,
	target string,
	category string,
	operation job.OperationType,
	data any,
) (string, *job.Response, error)

Query publishes a query job to a single target and waits for the response.

func (*Client) QueryBroadcast

func (c *Client) QueryBroadcast(
	ctx context.Context,
	target string,
	category string,
	operation job.OperationType,
	data any,
) (string, map[string]*job.Response, error)

QueryBroadcast publishes a query job to a broadcast target and collects all responses.

func (*Client) RetryJob

func (c *Client) RetryJob(
	ctx context.Context,
	jobID string,
	targetHostname string,
) (*CreateJobResult, error)

RetryJob creates a new job using the same operation data as an existing job. The original job is preserved. A "retried" status event is written to the original job's timeline linking to the new job.

func (*Client) SetDrainFlag

func (c *Client) SetDrainFlag(
	ctx context.Context,
	machineID string,
) error

SetDrainFlag writes the drain flag for an agent in the state KV bucket. The agent detects this flag on heartbeat and stops accepting jobs. Callers pass a machine ID (hex string, no sanitization needed).

func (*Client) SetMeterProvider

func (c *Client) SetMeterProvider(
	mp *sdkmetric.MeterProvider,
)

SetMeterProvider creates OTEL instruments for job metrics.

func (*Client) WriteAgentTimelineEvent

func (c *Client) WriteAgentTimelineEvent(
	ctx context.Context,
	hostname, event, message string,
) error

WriteAgentTimelineEvent writes an append-only timeline event for an agent state transition.

func (*Client) WriteJobResponse

func (c *Client) WriteJobResponse(
	_ context.Context,
	jobID, hostname string,
	responseData []byte,
	status string,
	errorMsg string,
	changed *bool,
) error

WriteJobResponse stores agent response data for a job.

func (*Client) WriteStatusEvent

func (c *Client) WriteStatusEvent(
	_ context.Context,
	jobID, event, hostname string,
	data map[string]interface{},
) error

WriteStatusEvent writes an append-only status event for a job. This eliminates race conditions by never updating existing keys.

type CreateJobResult

type CreateJobResult struct {
	JobID     string `json:"job_id"`
	Status    string `json:"status"`
	Revision  uint64 `json:"revision"`
	Timestamp string `json:"timestamp"`
}

CreateJobResult represents the result of creating a job.

type JobClient

type JobClient interface {
	// Generic dispatch operations — used by API handlers to submit jobs
	// without importing typed wrapper methods.
	Query(
		ctx context.Context,
		target string,
		category string,
		operation job.OperationType,
		data any,
	) (string, *job.Response, error)
	QueryBroadcast(
		ctx context.Context,
		target string,
		category string,
		operation job.OperationType,
		data any,
	) (string, map[string]*job.Response, error)
	Modify(
		ctx context.Context,
		target string,
		category string,
		operation job.OperationType,
		data any,
	) (string, *job.Response, error)
	ModifyBroadcast(
		ctx context.Context,
		target string,
		category string,
		operation job.OperationType,
		data any,
	) (string, map[string]*job.Response, error)

	// Job queue management operations
	GetQueueSummary(
		ctx context.Context,
	) (*job.QueueStats, error)
	GetJobStatus(
		ctx context.Context,
		jobID string,
	) (*job.QueuedJob, error)
	ListJobs(
		ctx context.Context,
		statusFilter string,
		limit int,
		offset int,
	) (*ListJobsResult, error)

	// Agent discovery
	ListAgents(
		ctx context.Context,
	) ([]job.AgentInfo, error)
	GetAgent(
		ctx context.Context,
		hostname string,
	) (*job.AgentInfo, error)

	// Agent timeline
	WriteAgentTimelineEvent(
		ctx context.Context,
		hostname, event, message string,
	) error
	GetAgentTimeline(
		ctx context.Context,
		hostname string,
	) ([]job.TimelineEvent, error)

	// Agent drain flag
	CheckDrainFlag(
		ctx context.Context,
		hostname string,
	) bool
	SetDrainFlag(
		ctx context.Context,
		hostname string,
	) error
	DeleteDrainFlag(
		ctx context.Context,
		hostname string,
	) error

	// Job deletion
	DeleteJob(
		ctx context.Context,
		jobID string,
	) error

	// Job retry
	RetryJob(
		ctx context.Context,
		jobID string,
		targetHostname string,
	) (*CreateJobResult, error)

	// Agent operations - used by agents for processing
	WriteStatusEvent(
		ctx context.Context,
		jobID string,
		event string,
		hostname string,
		data map[string]interface{},
	) error
	WriteJobResponse(
		ctx context.Context,
		jobID string,
		hostname string,
		responseData []byte,
		status string,
		errorMsg string,
		changed *bool,
	) error
	ConsumeJobs(
		ctx context.Context,
		streamName string,
		consumerName string,
		handler func(jetstream.Msg) error,
		opts *natsclient.ConsumeOptions,
	) error
	GetJobData(
		ctx context.Context,
		jobKey string,
	) ([]byte, error)
	CreateOrUpdateConsumer(
		ctx context.Context,
		streamName string,
		consumerConfig jetstream.ConsumerConfig,
	) error
}

JobClient defines the interface for interacting with the jobs system.

type ListJobsResult

type ListJobsResult struct {
	Jobs         []*job.QueuedJob
	TotalCount   int
	StatusCounts map[string]int
}

ListJobsResult represents the result of listing jobs with pagination.

type NATSClient

type NATSClient interface {
	Publish(
		ctx context.Context,
		subject string,
		data []byte,
	) error
	GetStreamInfo(
		ctx context.Context,
		streamName string,
	) (*jetstream.StreamInfo, error)
	KVPut(
		bucket string,
		key string,
		value []byte,
	) error
	ConsumeMessages(
		ctx context.Context,
		streamName string,
		consumerName string,
		handler natsclient.JetStreamMessageHandler,
		opts *natsclient.ConsumeOptions,
	) error
	CreateOrUpdateConsumerWithConfig(
		ctx context.Context,
		streamName string,
		consumerConfig jetstream.ConsumerConfig,
	) error
}

NATSClient defines the NATS operations needed by the job client.

type Options

type Options struct {
	// Timeout for waiting for job responses (default: 30s)
	Timeout time.Duration
	// KVBucket for job storage (required)
	KVBucket jetstream.KeyValue
	// RegistryKV is the KV bucket for agent registry (optional).
	RegistryKV jetstream.KeyValue
	// FactsKV is the KV bucket for agent facts (optional).
	FactsKV jetstream.KeyValue
	// StateKV is the KV bucket for persistent agent state (drain flags, timeline).
	StateKV jetstream.KeyValue
	// StreamName is the JetStream stream name (used to derive DLQ name).
	StreamName string
	// PKISigner signs job payloads when PKI is enabled. Nil when disabled.
	PKISigner PKISigner
	// TargetResolver resolves hostname targets to machine IDs for NATS
	// subject routing. When nil, targets are used as-is.
	TargetResolver func(string) string
}

Options configures the jobs client.

type PKISigner

type PKISigner interface {
	// Sign signs the given data with the signer's private key.
	Sign(data []byte) []byte
	// Fingerprint returns the SHA256 fingerprint of the signer's public key.
	Fingerprint() string
	// ControllerPublicKey returns the controller's public key for verifying
	// controller-signed messages. Returns nil if not set.
	ControllerPublicKey() ed25519.PublicKey
}

PKISigner signs and verifies payloads. Nil when PKI is disabled.

Jump to

Keyboard shortcuts

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