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

dispatchqueue

package
v0.0.0-...-e3c07e6 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package dispatchqueue holds the naming and priority rules shared by the dispatch scheduler (which publishes each claimed job to a queue) and the router-config document the platform serves (which advertises those same queues). Both sides compose names here so a job's destination and the document can never disagree on the shape.

Index

Constants

View Source
const (
	DefaultPoolCode   = "DEFAULT-POOL"
	DefaultPoolSuffix = "-" + DefaultPoolCode
)

DefaultPoolCode is the router's global fallback pool, and DefaultPoolSuffix the one structural read permitted on a composed pool code. A composed code's two halves may themselves contain hyphens, so nothing may split one back apart; a suffix test is unambiguous because the literal is fixed.

View Source
const SQSMaxNameLength = 80

SQSMaxNameLength is SQS's hard cap on a queue name, ".fifo" included.

View Source
const TenantPlatform = "platform"

TenantPlatform is the tenant segment reserved for platform-wide (client-less) dispatch jobs: they publish to {prefix}-platform-DEFAULT rather than to any client's lane.

A client whose identifier were literally "platform" would collide with that lane, so the identifier is refused at client creation. Identifiers are immutable after create, so that one check closes the collision permanently. The pool-code resolver and the router-config document builder use this same literal for the platform tenant rather than each declaring a copy.

Variables

View Source
var ErrTenantRequired = errors.New("dispatchqueue: tenant is required to compose a queue name")

ErrTenantRequired is returned by ComposeName for a blank tenant. A blank one would compose a shared lane rather than the per-client isolation the name exists to provide, so it is refused rather than papered over.

Functions

func ComposeName

func ComposeName(prefix, tenant string, priority Priority, sqs bool) (string, error)

ComposeName builds a dispatch queue's name: {prefix}-{tenant}-{priority}, ".fifo"-suffixed when sqs is true — FC-staging-acme-DEFAULT.fifo, FC-staging-acme-HIGH_PRIORITY.fifo.

Every deployed dispatch queue is FIFO (per-group ordering is load-bearing), so sqs alone decides both the suffix and whether the length cap applies.

A blank prefix omits that segment rather than failing: the requirement that a deployed SQS environment set one is enforced once, at startup, by SettingsFromEnv. A Postgres (dev) name with no prefix configured is a normal, if less tidy, name.

Only the tenant segment is sanitised, exactly as the existing convention sanitises: "_", "." and space each become "-". A conforming client identifier is already a lower-case slug containing none of them, so this is a no-op in the ordinary case and is kept defensively. The priority segment is never sanitised — HIGH_PRIORITY keeps its underscore, which is legal in an SQS queue name, and a Priority is always one of the two constants.

func ComposePoolCode

func ComposePoolCode(poolCode string, clientIdentifier *string) string

ComposePoolCode is the wire poolCode for a dispatch pool: {clientIdentifier}-{poolCode} when the pool is client-owned, and platform-{poolCode} when it is platform-level.

Platform-level pools take the platform- prefix rather than going out bare. The router merges this platform's document with other config sources and pools merge by code, first definition winning — so an unprefixed platform pool named, say, WEBHOOKS would silently inherit another tenant's settings of the same name, with only a merge-conflict log line to show for it.

This is the one place the composition happens: the scheduler stamps a claimed job's pool code with it and the router-config document names its pools with it, so a stamped code always matches a pool in the document.

func IsDefaultPoolCode

func IsDefaultPoolCode(code string) bool

IsDefaultPoolCode reports whether code names a fallback pool — the global DefaultPoolCode or any per-tenant {identifier}-DEFAULT-POOL, of which platform-DEFAULT-POOL is simply one more instance.

Types

type NameTooLongError

type NameTooLongError struct {
	Tenant   string
	Composed string
}

NameTooLongError is returned by ComposeName when the SQS form would exceed SQSMaxNameLength. tnt_clients.identifier is varchar(100), comfortably wider than SQS allows once the fixed segments are added, so this is a reachable condition rather than defensive dead code. The document builder omits that one tenant rather than failing the whole document.

func (*NameTooLongError) Error

func (e *NameTooLongError) Error() string

type Priority

type Priority string

Priority is a subscription's dispatch priority: which of the client's two queues — {prefix}-{client}-DEFAULT / {prefix}-{client}-HIGH_PRIORITY — a dispatch job raised from that subscription publishes to.

The value is the stored form of msg_subscriptions.queue and the wire value of the `queue` field on subscription create/update. The zero value is "not set", which the column permits and which reads as PriorityDefault on the publish path (see ForPublishing).

const (
	// PriorityDefault is the normal lane, and the fallback for anything the
	// publish path cannot make sense of.
	PriorityDefault Priority = "DEFAULT"
	// PriorityHighPriority is the expedited lane.
	PriorityHighPriority Priority = "HIGH_PRIORITY"
)

func ForJob

func ForJob(stored *string) (Priority, bool)

ForJob is the READ counterpart of Parse for msg_dispatch_jobs.queue — the job's OWN priority claim, distinct from ForPublishing's subscription fallback. It reports whether stored named a recognised priority at all (ok=false for nil, blank, or unrecognised legacy text), because DestinationResolver's resolution order (docs/spec/dispatch-job-priority.md R4) needs to tell "the job asked for a priority" from "the job said nothing, defer to the subscription": a job that explicitly stored DEFAULT must still win over a HIGH_PRIORITY subscription (job wins, R4/T6) rather than reading as unset, but a legacy job with no usable value of its own must fall through to the subscription lookup (R4/T7) exactly as it did before this column existed.

Never fails, for the same reason ForPublishing never fails: an error here would strand a job that happens to carry legacy text in its own column rather than just falling through to the subscription.

func ForPublishing

func ForPublishing(stored *string) Priority

ForPublishing is the READ counterpart of Parse, for the publish path: which queue a stored msg_subscriptions.queue value routes to.

Deliberately lenient where Parse is strict, and the asymmetry is the point. Write validation cannot reach rows that already exist: every row created before the `queue` field became writable holds NULL, and legacy rows hold arbitrary text — staging carries queue segments such as "workers-high". Absent, blank and unrecognised all yield PriorityDefault, and this never fails, because the scheduler calls it while claiming a batch: an error there would strand every job on the offending subscription rather than routing it to the normal lane.

The accepted cost: a legacy "workers-high" row is treated as normal priority with nothing announcing the downgrade. That was chosen over warning on it or refusing to publish; the remedy, if it ever bites, is a migration rather than a change here.

func Parse

func Parse(raw string) (Priority, error)

Parse is the WRITE path: it validates a queue value supplied on subscription create/update.

Matching is case-insensitive, deliberately. The SPA's subscription create form already sends `queue: "default"` and requires the field, so matching case-sensitively would reject every create from the UI — and the SPA is built from this repo's frontend but embedded by both servers, so the fix could not be confined to one side. "default", "Default" and "DEFAULT" all parse to PriorityDefault; only genuinely unknown text is rejected.

An empty or blank value means "no priority set" and returns the zero Priority with no error: the column stays nullable and create/update may omit the field entirely.

Jump to

Keyboard shortcuts

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