publisher

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: BSD-2-Clause Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SupportedPlaceholders = func() []string {
	names := make([]string, len(placeholders))
	for i, p := range placeholders {
		names[i] = p.name
	}
	return names
}()

SupportedPlaceholders is the ordered list of every placeholder name accepted in title, body, and string-valued frontmatter. Derived from the placeholders table. Exposed for callers (inventory validators, docs generators) that need the closed-enum list.

Functions

func NewNoopSender

func NewNoopSender() task.CreateCommandSender

NewNoopSender returns a task.CreateCommandSender whose SendCommand method is a no-op (returns nil). Wired by main.go and cmd/run-once when DRY_RUN=true to avoid Kafka client init. The publisher's dryRun guard skips the sender call anyway; the noop exists so the application can construct itself without a real Kafka broker.

Types

type FrontmatterFormatter added in v0.1.0

type FrontmatterFormatter interface {
	// Format returns the frontmatter for one published task. String
	// values in `operator` are rendered through the same placeholder
	// substitution as title/body (`{{date}}`, `{{iso-week}}`, etc.);
	// non-string values (ints, slices, maps) pass through unchanged.
	// `slug` and `date` parameterize the placeholder render; `date` is
	// the Berlin civil date the task fires for (the publisher converts
	// wall-clock once at the tick boundary).
	//
	// `autoAbortPrior` is stamped onto the result as the
	// `auto_abort_prior` key, AFTER operator keys are merged (so an
	// operator-supplied `auto_abort_prior` cannot override the spec-level
	// value) and BEFORE `created_by` is force-set (so `created_by` stays
	// the last provenance key). The value is a Go bool serialized as a
	// YAML boolean true/false.
	Format(
		operator lib.TaskFrontmatter,
		slug string,
		date schedule.Date,
		autoAbortPrior bool,
	) lib.TaskFrontmatter
}

FrontmatterFormatter builds the YAML frontmatter stamped onto every published task. The formatter is the single seam between operator- supplied frontmatter (from `Schedule.spec.template.frontmatter`) and the wire-level `task.CreateCommand.Frontmatter` payload: it seeds published-author defaults, renders placeholder tokens in string values via the publisher's closed placeholder set, merges operator keys (which may override the defaults), and force-sets the provenance key `created_by: recurring-task-creator` last so a Schedule CR cannot impersonate a different author.

func NewFrontmatterFormatter added in v0.1.0

func NewFrontmatterFormatter(renderer Renderer) FrontmatterFormatter

NewFrontmatterFormatter returns the default FrontmatterFormatter that renders string-valued frontmatter via the injected Renderer (same placeholder semantics as title/body). Stateless: safe to construct once and share across goroutines.

type PeriodToken added in v0.6.0

type PeriodToken string

PeriodToken is the period-anchored token string appended to a recurring task's title and fed into the UUID5 identifier — "YYYY-MM-DD" for daily, "YYYYWNN" for weekly, "YYYYWNN-<3-letter-weekday>" for weekday, "YYYY-MM" for monthly, "YYYYQN" for quarterly, "YYYY" for yearly. Wrapped in a named string type so calls that take both a slug and a token can't accept them in the wrong order without a compile error.

type PeriodTokenBuilder added in v0.6.0

type PeriodTokenBuilder interface {
	// Build returns the period-anchored token for (def, date). An unknown
	// RecurrenceKind is a build-time data error (closed enum, no valid
	// runtime reason for a new value), so the implementation returns an
	// error rather than a sentinel string.
	Build(ctx context.Context, def schedule.TaskDefinition, date schedule.Date) (PeriodToken, error)
}

PeriodTokenBuilder builds the period-anchored token for a given (definition, date) pair. The token formula honors def.Recurrence, def.PeriodOffset (only meaningful for the period-anchored kinds — Monthly, Quarterly, Yearly). For RecurrenceWeekday the weekday suffix is derived from the firing date (guaranteed to be in def.Weekdays on a firing day), not from a stored single value.

func NewPeriodTokenBuilder added in v0.6.0

func NewPeriodTokenBuilder() PeriodTokenBuilder

NewPeriodTokenBuilder returns the default PeriodTokenBuilder. Stateless.

type Publisher

type Publisher interface {
	// Publish builds a CreateCommand for (def, date) and sends it. The
	// returned error is wrapped with the slug and ISO date in its message.
	// Same (def, date) on a second call produces a byte-identical command.
	Publish(ctx context.Context, def schedule.TaskDefinition, date schedule.Date) error
}

Publisher turns one (TaskDefinition, Date) pair into a validated task.CreateCommand and sends it via the injected task.CreateCommandSender.

func NewPublisher

func NewPublisher(
	sender task.CreateCommandSender,
	renderer Renderer,
	formatter FrontmatterFormatter,
	identifierCreator TaskIdentifierCreator,
	dryRun bool,
) Publisher

NewPublisher returns a Publisher that sends through sender, rendering title + body placeholders via renderer, formatting frontmatter via formatter, and deriving the task identifier + period token via identifierCreator. The sender is invoked exactly once per Publish call (when inputs are valid). It validates the constructed command internally — see task.CreateCommandSender.SendCommand in github.com/bborbe/agent/command/task. When dryRun is true, the publisher logs the would-be CreateCommand and skips the sender call (intended for local smoke-testing via cmd/run-once).

type Renderer added in v0.2.0

type Renderer interface {
	// Render returns template with every placeholder substituted by
	// its rendered value for date. The slug parameter is reserved for
	// future placeholders that depend on the slug itself; the current
	// set does not. Pure: no I/O, no time, no state — same inputs on
	// a second call produce a byte-identical result.
	Render(template, slug string, date schedule.Date) string
}

Renderer substitutes the closed set of `{{...}}` placeholder tokens (see placeholders.go) inside an operator-authored template string. Same seam used by the publisher for title and body rendering and by FrontmatterFormatter for string-valued frontmatter entries — single definition of "what a placeholder is" across every render site.

func NewRenderer added in v0.2.0

func NewRenderer() Renderer

NewRenderer returns the default Renderer backed by the package-level placeholders table. Stateless: safe to construct once and share across goroutines.

type TaskIdentifierCreator added in v0.6.0

type TaskIdentifierCreator interface {
	// Create returns the (identifier, periodToken) pair for (def, date).
	// def.PeriodOffset shifts the period token for the period-anchored
	// recurrence kinds (Monthly / Quarterly / Yearly); the shift feeds
	// into the UUID5 input, so different offsets produce different
	// identifiers for the same fire date.
	Create(
		ctx context.Context,
		def schedule.TaskDefinition,
		date schedule.Date,
	) (lib.TaskIdentifier, PeriodToken, error)
}

TaskIdentifierCreator derives the deterministic UUID5 identifier AND the period-anchored title-suffix token for a recurring task in one call. The publisher needs both — the identifier is the dedup key on the downstream controller, the period token is the title suffix — and they share the same period-token computation, so returning them together avoids re-deriving the token at the call site.

The identifier is UUID5(uuidNamespace, "recurring-<slug>-<token>"), where <token> is the result of PeriodTokenBuilder.Build for the same (def, date). Same input on a second call produces the same identifier across processes, redeploys, and replays — this is the contract the controller's de-dup relies on.

func NewTaskIdentifierCreator added in v0.6.0

func NewTaskIdentifierCreator(builder PeriodTokenBuilder) TaskIdentifierCreator

NewTaskIdentifierCreator returns the default TaskIdentifierCreator backed by the given PeriodTokenBuilder. The builder is the only dependency — the UUID5 namespace is a package constant.

Jump to

Keyboard shortcuts

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