deploymentpatch

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package deploymentpatch builds the deployment-patch primitives the watch loop needs: a managementapi.DeploymentPatchPoint describing a source tree (BuildPatchPoint) and the patch ops between two points (BuildPatchOps).

The per-file content hashes here must reproduce Truss's Python implementation bit-for-bit: the server-side build computes the signature with Python (truss/truss_handle/patch/{signature,dir_signature}.py), so a Go watch client that diffs against it has to match exactly.

Index

Constants

This section is empty.

Variables

View Source
var ErrNeedsFullDeploy = errors.New("deploymentpatch: change cannot be patched, full deploy required")

ErrNeedsFullDeploy signals that the change between two patch points cannot be expressed as a patch and the deployment must be re-pushed. It corresponds to calc_truss_patch returning None (the caller should tell the user to run a full `baseten model push`). Only two changes trigger it, matching Truss: removing config.yaml, and any change strictly under the data directory.

Functions

func BuildPatchOps

BuildPatchOps computes the patch ops that take Prev to Next, porting truss/truss_handle/patch/calc_patch.py (calc_truss_patch). It returns ErrNeedsFullDeploy when the change can't be patched.

Unlike Truss, which re-globs and re-hashes the directory inside _calc_changed_paths, both sides already carry content_hashes (Next from BuildPatchPoint, Prev from the server), so we diff those maps directly. Likewise the config / env-var / external-data / requirement ops are derived from each point's stored Config text and Requirements list rather than being gated on config.yaml or the requirements file appearing in the changed paths: those fields only differ when Truss would have entered its config block, so the result is equivalent (see the per-section comments below).

func BuildPatchPoint

BuildPatchPoint walks opts.Dir and returns the patch point describing its current source state: the per-path content hashes, the verbatim config.yaml, and the requirements resolved from the config's requirements file (empty when requirements are inline).

This reproduces Truss's watch-client signature (calc_truss_signature over the local directory with the .truss_ignore patterns), so the result can be diffed against the server's patch state.

func CompileTrussIgnore

func CompileTrussIgnore(contents []byte) modelarchive.IgnoreFileFunc

CompileTrussIgnore compiles raw .truss_ignore contents into an ignore predicate using gitignore semantics.

func ResolveTrussIgnore

func ResolveTrussIgnore(dir string) (modelarchive.IgnoreFileFunc, error)

ResolveTrussIgnore returns the ignore predicate for a model directory: a .truss_ignore file at the root of dir takes precedence, otherwise the built-in defaults (modelarchive.DefaultIgnoreFile) apply.

The same predicate must drive both the archive upload (push) and the local source signature (watch); if they disagree on which paths exist, the watch client's content hashes will not line up with the server's.

func Watch

func Watch(ctx context.Context, opts WatchOptions) (<-chan WatchEvent, error)

Watch watches opts.Dir recursively and returns a channel that receives one WatchEvent per debounced batch of changes to non-ignored paths. Changes to ignored paths (per ResolveTrussIgnore) never wake the caller.

Mirroring Truss (which watches recursively and filters each event through one ignore predicate), the same ignore drives both the watch and the patch computation. An entry-ignored directory (.git) is pruned from the watch entirely; a contents-only-ignored directory (__pycache__, kept as a null entry for hash parity) is still watched, but its events are filtered out.

The filter is best-effort, not authoritative: a spurious wake is harmless because the caller re-derives the patch point on each tick and finds zero ops.

The channel is closed when ctx is cancelled or the watcher fails. A setup failure (bad directory, watcher creation) is returned synchronously instead.

Types

type BuildPatchOpsOptions

type BuildPatchOpsOptions struct {
	// Dir is the model directory holding the current (Next) source. Required;
	// file contents for model-code and package ops are read from here.
	Dir string
	// Prev is the patch point being patched off of (the server's running or
	// pending point). Required.
	Prev *managementapi.DeploymentPatchPoint
	// Next is the current local source state, as built by [BuildPatchPoint].
	// Required.
	Next *managementapi.DeploymentPatchPoint
	// HotReload requests hot reload. Mirroring Truss, it only takes effect when
	// every resulting op is a model-code change; mixed patches fall back to a
	// cold restart.
	HotReload bool
}

BuildPatchOpsOptions configures BuildPatchOps.

type BuildPatchPointOptions

type BuildPatchPointOptions struct {
	// Dir is the model directory whose source state is captured. Required.
	Dir string
}

BuildPatchPointOptions configures BuildPatchPoint.

type WatchEvent

type WatchEvent struct {
	Err error
}

WatchEvent is one item on the channel returned by Watch. A zero value signals a debounced batch of filesystem changes under the watched directory. A non-nil Err means the underlying watcher failed and the channel is about to close; the caller should stop watching.

type WatchOptions

type WatchOptions struct {
	// Dir is the model directory to watch. Required.
	Dir string
	// DebounceWindow coalesces a burst of filesystem events into a single tick.
	// Defaults to 100ms when zero.
	DebounceWindow time.Duration
}

WatchOptions configures Watch.

Jump to

Keyboard shortcuts

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