blobfish

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package blobfish is the generated Blobfish widget.

Edit the widget document and regenerate; edits here are overwritten.

Index

Constants

View Source
const (
	BlobfishName    = "Blobfish"
	BlobfishRegion  = "widget.candaws.blobfish"
	BlobfishPalette = "fieldStation"
	BlobfishTitleID = "widget.candaws.blobfish-title"
)

This widget's identity. The region is the only one that crosses the wire: a patch names it, so changing it is a client-visible change. The palette is a name a host resolves to values; this widget carries no colour of its own. The title id is what the widget's landmark is labelled by.

View Source
const (
	BlobfishEventReplicaReportFieldGeneration   = "generation"
	BlobfishEventReplicaReportFieldStorageClass = "storage_class"
	BlobfishEventReplicaReportFieldObjects      = "objects"
	BlobfishEventReplicaReportFieldWriteAcks    = "write_acks"
	BlobfishEventReplicaReportFieldLaggingZones = "lagging_zones"
	BlobfishEventReplicaReportFieldWritable     = "writable"
	BlobfishEventReplicaReportFieldReadable     = "readable"
)

The wire field names each event carries. They are the other half of an event's contract: the widget reads these out of a delivery, and whatever produced the delivery wrote them in. Registration.Payloads carries the same names as data, for a host that fills an event it cannot name at compile time.

View Source
const (
	BlobfishEventReplicaReport = "widget.candaws.blobfish.report"
)

The wire names this widget accepts. The set is exhaustive and default-deny: a name absent from the registration is refused before any reducer runs.

Variables

View Source
var (
	// ErrStorageClass is an empty storage class. The card interpolates it into
	// a stat line, and an empty one renders as a sentence with a hole in it.
	ErrStorageClass = errors.New("blobfish: the storage class is empty")

	// ErrCadence is a put cadence that is not positive.
	ErrCadence = errors.New("blobfish: the put cadence is not positive")

	// ErrReplicaDelay is a zone latency that is not positive, or a jitter
	// spread that is negative.
	ErrReplicaDelay = errors.New("blobfish: the zone latency is not positive")

	// ErrPatience is a coordinator patience that does not clear the fast
	// zones' worst case. A coordinator that gives up before a healthy zone can
	// answer never reaches a quorum, which looks like an outage rather than
	// like a configuration fault.
	ErrPatience = errors.New("blobfish: the coordinator's patience does not clear the zone latency")

	// ErrSlowZone is a slow zone outside [-1, zoneCount).
	ErrSlowZone = errors.New("blobfish: the slow zone is not a zone")

	// ErrSlowFactor is a slow factor below one: a slow zone that is not slower.
	ErrSlowFactor = errors.New("blobfish: the slow factor is below one")

	// ErrRepairInterval is a repair interval that is not positive. Without one
	// the third copy never catches up, and "eventually consistent" becomes
	// "consistent at no point".
	ErrRepairInterval = errors.New("blobfish: the repair interval is not positive")
)

The faults this engine reports, each a sentinel.

Functions

func BlobfishView

func BlobfishView(state BlobfishState) templ.Component

BlobfishView draws the Blobfish widget's default live region.

func BlobfishViewAt

func BlobfishViewAt(state BlobfishState, region string) templ.Component

BlobfishViewAt draws one instance in its host-assigned live region.

Every value in it is a pure read of state and region: equal inputs render byte-identical markup: that comparison is what suppresses a patch nobody needs.

func ReportFields

func ReportFields(view StoreView) map[string]string

ReportFields is one store view as the replicaReport event carries it.

Types

type Blobfish

type Blobfish[I live.IIdentity] struct {
	// contains filtered or unexported fields
}

Blobfish is the generated Blobfish widget.

I is the HOST's identity type, threaded through and never read: a widget document names no host, no address and no credential, so nothing here can look at an identity. It is a type parameter because the SDK's contract carries one — live.Session stopped erasing the application's identity type on 2026-09-03 — and a generated widget must fit whatever host registers it.

func NewBlobfish

func NewBlobfish[I live.IIdentity]() *Blobfish[I]

NewBlobfish returns the widget a host registers, instantiated on that host's own identity type.

func NewBlobfishAt

func NewBlobfishAt[I live.IIdentity](region string) *Blobfish[I]

NewBlobfishAt gives one instance its host-assigned region. The host validates region syntax and uniqueness when assembling its live configuration.

func (*Blobfish[I]) Dirty

func (instance *Blobfish[I]) Dirty(previous BlobfishState, next BlobfishState) bool

Dirty reports whether a transition may have changed this widget's markup: the state fields its bindings, its predicates and its tick read, and no others.

func (*Blobfish[I]) Mount

func (instance *Blobfish[I]) Mount(
	ctx context.Context, session live.Session[I],
) (BlobfishState, []live.Effect[I], error)

Mount opens one session's copy of the widget. It schedules no effect: the streams this widget declared are the host's to open, because a widget document names no host, no address and no credential.

func (*Blobfish[I]) Reduce

func (instance *Blobfish[I]) Reduce(
	state BlobfishState, event live.Event,
) (BlobfishState, []live.Effect[I])

Reduce is the pure transition from one state to the next. It performs no I/O, reads no clock and mutates nothing it was given.

func (*Blobfish[I]) Register

func (instance *Blobfish[I]) Register() widget.Registration

Register declares this instance's definition and assigned region.

Events are the names a browser may send; Internal are the names only a declared stream delivers, which the host routes without registering.

func (*Blobfish[I]) Render

func (instance *Blobfish[I]) Render(state BlobfishState) templ.Component

Render draws the widget's live region. It is a pure function of state: equal state renders byte-identical markup.

func (*Blobfish[I]) Snapshot

func (instance *Blobfish[I]) Snapshot(state BlobfishState) widget.Snapshot

Snapshot projects state into ordered name/value pairs, in state-field declaration order.

func (*Blobfish[I]) Unmount

func (instance *Blobfish[I]) Unmount(ctx context.Context, session live.Session[I], state BlobfishState)

Unmount releases what the session held. This widget holds nothing.

type BlobfishState

type BlobfishState struct {
	// Generation is the "generation" state field, declared type counter.
	Generation uint64

	// StorageClass is the "storageClass" state field, declared type text.
	StorageClass string

	// Objects is the "objects" state field, declared type count.
	Objects int64

	// WriteAcks is the "writeAcks" state field, declared type count.
	WriteAcks int64

	// LaggingZones is the "laggingZones" state field, declared type count.
	LaggingZones int64

	// Writable is the "writable" state field, declared type flag.
	Writable bool

	// Readable is the "readable" state field, declared type flag.
	Readable bool

	// CatchingUp is the "catchingUp" state field, declared type flag.
	CatchingUp bool
}

BlobfishState is this widget's own state, and the type argument every method below is written in. The host holds it without knowing it; nothing in this file asserts it back, because nothing in this file ever loses it.

func (BlobfishState) AckLegendLabel

func (state BlobfishState) AckLegendLabel() string

AckLegendLabel is the "ackLegendLabel" label.

func (BlobfishState) ClassStatLabel

func (state BlobfishState) ClassStatLabel() string

ClassStatLabel is the "classStatLabel" label.

func (BlobfishState) Consistent

func (state BlobfishState) Consistent() bool

Consistent is the "consistent" predicate.

func (BlobfishState) CoordinatorCaptionLabel

func (state BlobfishState) CoordinatorCaptionLabel() string

CoordinatorCaptionLabel is the "coordinatorCaptionLabel" label.

func (BlobfishState) CoordinatorCaptionText

func (state BlobfishState) CoordinatorCaptionText() string

CoordinatorCaptionText is the "coordinatorCaptionText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) CoordinatorLabel

func (state BlobfishState) CoordinatorLabel() string

CoordinatorLabel is the "coordinatorLabel" label.

func (BlobfishState) DurabilityIndicatorTone

func (state BlobfishState) DurabilityIndicatorTone() string

DurabilityIndicatorTone is the "durabilityIndicator" indicator's tone: positive while its predicate holds, warning otherwise.

func (BlobfishState) DurabilityStatusLabel

func (state BlobfishState) DurabilityStatusLabel() string

DurabilityStatusLabel is the "durabilityStatusLabel" label.

func (BlobfishState) DurabilityStatusText

func (state BlobfishState) DurabilityStatusText() string

DurabilityStatusText is the "durabilityStatusText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) Durable

func (state BlobfishState) Durable() bool

Durable is the "durable" predicate.

func (BlobfishState) MotionActive

func (state BlobfishState) MotionActive() bool

MotionActive is this widget's compiled motion gate: everything its motion block requires, and none of what it forbids. The host's own connection status is the gate's other half and is applied by the stylesheet, so an animation cannot run against a dead connection whatever this returns.

func (BlobfishState) MotionActiveText

func (state BlobfishState) MotionActiveText() string

MotionActiveText renders the gate into the attribute the stylesheet selects on.

func (BlobfishState) MotionTickID

func (state BlobfishState) MotionTickID() string

MotionTickID is the scene's identity for one tick.

Every animation is finite and none repeats, so what starts one again is a new element: the scene carries this as its id, the tick advances, and the picture moves exactly as often as the data does.

func (BlobfishState) MotionTickIDAt

func (state BlobfishState) MotionTickIDAt(region string) string

MotionTickIDAt namespaces the scene's tick identity under its live instance.

func (BlobfishState) ObjectStatLabel

func (state BlobfishState) ObjectStatLabel() string

ObjectStatLabel is the "objectStatLabel" label.

func (BlobfishState) ObjectStatText

func (state BlobfishState) ObjectStatText() string

ObjectStatText is the "objectStatText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) QuorumStatLabel

func (state BlobfishState) QuorumStatLabel() string

QuorumStatLabel is the "quorumStatLabel" label.

func (BlobfishState) QuorumStatText

func (state BlobfishState) QuorumStatText() string

QuorumStatText is the "quorumStatText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) QuorumWrites

func (state BlobfishState) QuorumWrites() bool

QuorumWrites is the "quorumWrites" predicate.

func (BlobfishState) RepairLegendLabel

func (state BlobfishState) RepairLegendLabel() string

RepairLegendLabel is the "repairLegendLabel" label.

func (BlobfishState) RepairStatLabel

func (state BlobfishState) RepairStatLabel() string

RepairStatLabel is the "repairStatLabel" label.

func (BlobfishState) RepairStatText

func (state BlobfishState) RepairStatText() string

RepairStatText is the "repairStatText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) SceneDescriptionLabel

func (state BlobfishState) SceneDescriptionLabel() string

SceneDescriptionLabel is the "sceneDescriptionLabel" label.

func (BlobfishState) Serving

func (state BlobfishState) Serving() bool

Serving is the "serving" predicate.

func (BlobfishState) StoreDescriptionText

func (state BlobfishState) StoreDescriptionText() string

StoreDescriptionText is the "storeDescriptionText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) TitleLabel

func (state BlobfishState) TitleLabel() string

TitleLabel is the "titleLabel" label.

func (BlobfishState) WriteLegendLabel

func (state BlobfishState) WriteLegendLabel() string

WriteLegendLabel is the "writeLegendLabel" label.

func (BlobfishState) ZoneCaptionLabel

func (state BlobfishState) ZoneCaptionLabel() string

ZoneCaptionLabel is the "zoneCaptionLabel" label.

func (BlobfishState) ZoneCaptionText

func (state BlobfishState) ZoneCaptionText() string

ZoneCaptionText is the "zoneCaptionText" binding. The first matching clause wins and the otherwise arm is always present, so it is total.

func (BlobfishState) ZoneOneLabel

func (state BlobfishState) ZoneOneLabel() string

ZoneOneLabel is the "zoneOneLabel" label.

func (BlobfishState) ZoneThreeLabel

func (state BlobfishState) ZoneThreeLabel() string

ZoneThreeLabel is the "zoneThreeLabel" label.

func (BlobfishState) ZoneTwoLabel

func (state BlobfishState) ZoneTwoLabel() string

ZoneTwoLabel is the "zoneTwoLabel" label.

type Config

type Config struct {
	// StorageClass is the tier this store's objects are in, and is the text the
	// card interpolates. Glacial is cheaper because retrieving from it is
	// billed separately.
	StorageClass string

	// Cadence is how often the bucket puts an object.
	Cadence time.Duration

	// ReplicaDelay is the base latency of a zone, and DelaySpread is the width
	// of the per-zone jitter added to it.
	ReplicaDelay time.Duration
	DelaySpread  time.Duration

	// SlowZone is the index of the zone the quorum does not wait for, or -1 for
	// a store whose zones are all the same speed. It is the one the repair
	// channel runs to, and the one the pricing page calls eventually
	// consistent so the other two do not have to be.
	SlowZone int

	// SlowFactor multiplies the slow zone's latency.
	SlowFactor int

	// Patience is how long the coordinator waits for a quorum before giving
	// up. It must clear a fast zone's worst case, or no write ever lands.
	Patience time.Duration

	// RepairInterval is how often the repairer probes every zone and issues a
	// repair write to whichever is behind.
	RepairInterval time.Duration

	// Seed seeds the per-zone jitter streams.
	Seed int64
}

Config is one store's shape and pace. Every field is required.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig is the demo's own pace: three zones, one of them six times slower than the other two, and a repair sweep often enough that the third copy visibly catches up.

func (Config) Validate

func (config Config) Validate() error

Validate reports the first fault in a configuration.

type Store

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

Store is one Blobfish store running in one process.

It holds channels and nothing else. The bucket's key map, each zone's generation, the coordinator's in-flight write and the published view are all locals of goroutines Store.Run starts.

func NewStore

func NewStore(config Config) (*Store, error)

NewStore builds a store and starts nothing.

func (*Store) Config

func (store *Store) Config() Config

Config is the configuration this store was built from.

func (*Store) Run

func (store *Store) Run(ctx context.Context) error

Run starts every goroutine and returns when the context ends and all of them have stopped. The only error it has is being called twice.

func (*Store) Watch

func (store *Store) Watch(ctx context.Context) (<-chan StoreView, error)

Watch is the store stream the card's declared source resolves to.

type StoreView

type StoreView struct {
	// Sequence is this view's position in the stream, from 1.
	Sequence uint64

	// Generation is the highest generation the coordinator has minted. It is
	// never reused for a key, which is what makes it the card's tick.
	Generation uint64

	// StorageClass is the tier this store's objects are in. It is the fleet's
	// second text field, and it never changes for a given store — which is
	// itself worth having in the view, because a card that can render a string
	// it did not compute is a card that can render a name.
	StorageClass string

	// Objects is how many objects the bucket holds.
	Objects int

	// WriteAcks is how many zones answered the last write before the
	// coordinator stopped counting.
	WriteAcks int

	// LaggingZones is how many zones the last repair sweep found behind.
	LaggingZones int

	// Writable is whether the last write reached its quorum, and Readable
	// whether the last read reached its own.
	Writable bool
	Readable bool
}

StoreView is what the store tells anybody, and it is deliberately the shape the Blobfish card's `replicaReport` event carries.

func (*StoreView) Acks

func (view *StoreView) Acks(counted int)

Acks records how many zones answered the last write.

It is a method rather than a field assignment because the count is capped at the zone set: a coordinator that stopped counting at the quorum reports the quorum, and a view claiming more acknowledgements than there are zones would be a card reporting durability nobody has.

func (StoreView) Durable

func (view StoreView) Durable() bool

Durable reports whether the last write reached the write quorum.

func (StoreView) Serving

func (view StoreView) Serving() bool

Serving reports whether both quorums were met, which is what the card's `serving` predicate composes.

Jump to

Keyboard shortcuts

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