Skip to content

bridge

import "github.com/danmestas/dagnats/bridge"

Index

func RegisterBridgeMetrics

func RegisterBridgeMetrics(m metric.Meter, b *Bridge) (metric.Registration, error)

RegisterBridgeMetrics wires the bridge’s observable instruments to m and returns the registration so a caller can unregister it.

The ackmap size is an observable gauge rather than an up/down counter deliberately. A counter requires every mutation site — store, resolve, reap, cap eviction — to Add the right delta forever, and drifts permanently the moment one is missed. This instrument was previously an Int64UpDownCounter with no Add call anywhere, so it reported a constant zero: indistinguishable from an idle bridge, and wrong the entire time it existed. A callback reading AckMap.Count() cannot drift, because it reports the real value at every collection.

Mirrors RegisterSchedulerMetrics (internal/trigger/metrics.go): a standalone registration function rather than construction inside NewBridge, so the error is returned to a caller that can assert on it instead of being discarded at startup.

type AckMap

AckMap tracks in-flight tasks for HTTP workers. Maps task_id ({runID}.{stepID}) to the NATS message so the bridge can ack/nak on behalf of the HTTP client when it resolves the task.

Thread-safe: multiple poll/resolve handlers run concurrently.

Bounded two ways, because an HTTP worker that dies mid-task never resolves and would otherwise leak its entry for the process lifetime: entries older than ackMapReapAfter are swept on insert, and ackMapMaxEntries caps the map between sweeps.

The sweep runs on insert rather than on a ticker because Bridge has no shutdown path to stop a goroutine against, and because entries are only ever created by traffic — an idle bridge cannot grow.

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

func NewAckMap

func NewAckMap() *AckMap

NewAckMap creates an empty AckMap ready for use.

func (*AckMap) Count

func (am *AckMap) Count() int64

Count returns the number of in-flight tasks.

func (*AckMap) Delete

func (am *AckMap) Delete(taskID string)

Delete removes a task from the map after resolution.

func (*AckMap) Load

func (am *AckMap) Load(taskID string) (jetstream.Msg, bool)

Load retrieves the NATS message for the given task ID. Returns (nil, false) if not found.

Deliberately does not reap: a resolve arriving concurrently with the reaper must not race into a “task not found” that the worker cannot distinguish from a genuine unknown-task error.

func (*AckMap) Store

func (am *AckMap) Store(taskID string, msg jetstream.Msg)

Store saves a NATS message keyed by task ID, stamped with the insertion time. Sweeps expired entries and enforces the size cap before inserting. Panics on empty taskID or nil msg — both are programmer errors.

type Bridge

Bridge is an HTTP-to-NATS gateway that lets non-Go workers interact with DagNats over HTTP. Three deep endpoints expose the full worker lifecycle: connect, poll, and resolve.

Authentication: when DAGNATS_BRIDGE_TOKEN env var is set, all requests must include Authorization: Bearer <token>. When unset, all requests are allowed (development mode).

Every outbound NATS publish goes through *natsutil.TracingPublisher so W3C trace context (traceparent / tracestate) is auto-injected onto the outgoing message. This continues distributed traces from the inbound HTTP request into the NATS plane — without it, the trace ID would terminate at the HTTP boundary for non-Go workers.

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

func NewBridge

func NewBridge(pub *natsutil.TracingPublisher) *Bridge

NewBridge creates a Bridge. Panics on nil pub — a programmer error at startup. The TracingPublisher wraps both *nats.Conn and jetstream.JetStream and is the only legal publish surface inside this package (CI lint enforces this).

Binds optional KV buckets for checkpoints and signals (nil if not present).

func (*Bridge) Handler

func (b *Bridge) Handler() http.Handler

Handler returns an http.Handler with the three bridge routes. The mux routes are:

  • POST /v1/workers/connect
  • POST /v1/tasks/poll
  • POST /v1/tasks/ (resolve, path includes task ID)

Generated by gomarkdoc