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

block_store_writeback

package
v0.57.30 Latest Latest
Warning

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

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

Documentation

Overview

Package block_store_writeback keeps every block write in a local store and uploads it to a remote store in the background.

A write is acknowledged once the local store holds the block and a durable marker names it. Upload drains the markers to the remote store and clears each marker only after the remote store holds its block, so writes made while the remote is unreachable upload after it returns, across restarts. Backfill queues the blocks stored before a remote was chosen.

A marker waits a settle age before it uploads, so a block the garbage collector sweeps meanwhile never reaches the remote: the upload finds the block gone and drops its marker.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type EvictResult

type EvictResult struct {
	// Evicted is the number of local values dropped.
	Evicted int
	// EvictedBytes is the recorded size of the dropped values.
	EvictedBytes int64
	// Requeued is the number of entries the caller kept, queued at the new
	// epoch.
	Requeued int
	// Refused is the number of blocks kept because the remote store may not
	// hold them: a marker awaits upload, or the remote does not report them.
	Refused int
}

EvictResult reports what an eviction pass did.

type Mark

type Mark struct {
	// Hash is the block hash.
	Hash *hash.Hash
	// Size is the block size in bytes.
	Size int64
	// At is when the block was written. The zero time uploads it without
	// waiting to settle, as a backfill does.
	At time.Time
}

Mark names a written block.

type MarkFunc

type MarkFunc func(ctx context.Context, marks []Mark) error

MarkFunc durably records written blocks before their writes are acknowledged. A batch write passes all of its blocks in one call.

type MarkingStore

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

MarkingStore acknowledges writes only after mark retains each written block.

A write that fails to mark returns the error with the block stored; repeating the write repairs the marker.

func NewMarkingStore

func NewMarkingStore(store block.StoreOps, mark MarkFunc) *MarkingStore

NewMarkingStore wraps store, calling mark after each successful write.

func (*MarkingStore) BeginDeferFlush

func (m *MarkingStore) BeginDeferFlush()

BeginDeferFlush forwards the GC ref-batch scope to the inner store.

func (*MarkingStore) BeginReadOperation

func (m *MarkingStore) BeginReadOperation(ctx context.Context) (block.StoreOps, func(), error)

BeginReadOperation opens a read scope on the inner store.

func (*MarkingStore) EndDeferFlush

func (m *MarkingStore) EndDeferFlush(ctx context.Context) error

EndDeferFlush forwards the GC ref-batch scope to the inner store.

func (*MarkingStore) GetBlock

func (m *MarkingStore) GetBlock(ctx context.Context, ref *block.BlockRef) ([]byte, bool, error)

GetBlock gets a block by reference.

func (*MarkingStore) GetBlockExists

func (m *MarkingStore) GetBlockExists(ctx context.Context, ref *block.BlockRef) (bool, error)

GetBlockExists checks if a block exists.

func (*MarkingStore) GetBlockExistsBatch

func (m *MarkingStore) GetBlockExistsBatch(ctx context.Context, refs []*block.BlockRef) ([]bool, error)

GetBlockExistsBatch forwards batched existence probes to the inner store.

func (*MarkingStore) GetHashType

func (m *MarkingStore) GetHashType() hash.HashType

GetHashType returns the inner store hash type.

func (*MarkingStore) GetStoreParts

func (m *MarkingStore) GetStoreParts() []block.StorePart

GetStoreParts returns the wrapped store.

func (*MarkingStore) GetStoredBlock

func (m *MarkingStore) GetStoredBlock(ctx context.Context, ref *block.BlockRef) (*block.StoredBlock, error)

GetStoredBlock forwards to the inner store.

func (*MarkingStore) GetSupportedFeatures

func (m *MarkingStore) GetSupportedFeatures() block.StoreFeature

GetSupportedFeatures returns the inner store native feature bitset.

func (*MarkingStore) HoldCompleteRoots

func (m *MarkingStore) HoldCompleteRoots(ctx context.Context, refs []*block.BlockRef) ([]bool, error)

HoldCompleteRoots holds completion proofs under the inner stage. A hold writes no block, so there is nothing to mark.

func (*MarkingStore) MarkRootsComplete

func (m *MarkingStore) MarkRootsComplete(ctx context.Context, roots []*block.BlockRef) error

MarkRootsComplete forwards the durable World proof.

func (*MarkingStore) OpenStage

func (m *MarkingStore) OpenStage(ctx context.Context) (block.StoreOps, func(), error)

OpenStage wraps a stage opened on the inner store, so staged writes are marked for upload like any other write.

func (*MarkingStore) PinRoot

func (m *MarkingStore) PinRoot(ctx context.Context, ref *block.BlockRef) (func(), error)

PinRoot forwards a reader pin to the inner store.

func (*MarkingStore) PutBlock

func (m *MarkingStore) PutBlock(ctx context.Context, data []byte, opts *block.PutOpts) (*block.BlockRef, bool, error)

PutBlock stores a block and marks it, even when it already existed.

func (*MarkingStore) PutBlockBatch

func (m *MarkingStore) PutBlockBatch(ctx context.Context, entries []*block.PutBatchEntry) ([]bool, error)

PutBlockBatch marks every successful non-tombstone write in one call. A failed marker returns an error; repeating the batch repairs the markers.

func (*MarkingStore) ReleaseRoots

func (m *MarkingStore) ReleaseRoots(ctx context.Context, refs []*block.BlockRef) error

ReleaseRoots forwards staging release to the underlying store.

func (*MarkingStore) RmBlock

func (m *MarkingStore) RmBlock(ctx context.Context, ref *block.BlockRef) error

RmBlock removes a block.

func (*MarkingStore) RootsComplete

func (m *MarkingStore) RootsComplete(ctx context.Context, refs []*block.BlockRef) ([]bool, error)

RootsComplete checks the inner store's World proofs.

func (*MarkingStore) SetRetainedRoots

func (m *MarkingStore) SetRetainedRoots(ctx context.Context, entries []*block.PutBatchEntry, roots []block.NamedRoot) error

SetRetainedRoots forwards durable root ownership to the inner store and marks the blocks it wrote.

func (*MarkingStore) StatBlock

func (m *MarkingStore) StatBlock(ctx context.Context, ref *block.BlockRef) (*block.BlockStat, error)

StatBlock returns block metadata.

func (*MarkingStore) SupportsRootRetention

func (m *MarkingStore) SupportsRootRetention() bool

SupportsRootRetention reports the inner store's root ownership capability. Retiring a local root lets the collector sweep superseded blocks; a marker whose block was swept is dropped without upload.

func (*MarkingStore) Sync

func (m *MarkingStore) Sync(ctx context.Context) (bool, error)

Sync forwards the durability barrier to the inner store.

type Policy

type Policy struct {
	// Settle is how long a block stays queued before it uploads.
	Settle time.Duration
	// MaxPendingBytes uploads the oldest blocks before they settle while the
	// queued bytes exceed it. Zero sets no limit.
	MaxPendingBytes int64
	// ResidentHigh is the resident byte budget: past it, eviction drops the
	// uploaded blocks read least recently. Zero evicts nothing.
	ResidentHigh int64
	// ResidentLow is where eviction stops, at most ResidentHigh. Eviction can
	// drop only uploaded blocks, so queued bytes past it upload before they
	// settle.
	ResidentLow int64
}

Policy sets when queued blocks upload and how many bytes the local store keeps.

type Status

type Status struct {
	// Enabled reports whether writes are queued for upload.
	Enabled bool
	// Pending is the number of blocks awaiting upload.
	Pending int
	// PendingBytes is the size of the blocks awaiting upload.
	PendingBytes int64
	// Oldest is the write time of the first block awaiting upload, while
	// Pending is not zero. Every block written before it has uploaded.
	Oldest time.Time
	// Err is the last upload failure, cleared by the next successful batch.
	Err error
	// Target is the remote every block stored before it was chosen is queued
	// for, empty until a backfill completes.
	Target string
	// Policy sets when queued blocks upload and the resident budget.
	Policy Policy
	// EvictableBytes is the size of the uploaded blocks the eviction queue
	// holds. It can overcount blocks the garbage collector swept until an
	// eviction pass meets their entries.
	EvictableBytes int64
	// EvictedBytes is the size of the values eviction dropped since the store
	// opened.
	EvictedBytes int64
	// Refills is the number of evicted blocks read back from the remote since
	// the store opened. Each one was a read that waited on the remote.
	Refills int64
}

Status is the upload state of a Store.

func (Status) EvictBytes

func (s Status) EvictBytes() int64

EvictBytes returns how many uploaded bytes a pass drops to bring the resident bytes from past the high mark down to the low mark, or zero.

func (Status) ResidentBytes

func (s Status) ResidentBytes() int64

ResidentBytes is the size of the store's blocks the local store holds: the blocks awaiting upload and the uploaded blocks not yet evicted.

type Store

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

Store is a local block store whose writes queue for upload.

func NewStore

func NewStore(
	ctx context.Context,
	local, values block.StoreOps,
	markers kvtx.Store,
	enabled bool,
) (*Store, error)

NewStore builds a Store over local, counting the markers left by a previous run. Queued blocks upload at once until SetPolicy sets a settle age. values holds the same blocks as local without its ownership tracking.

When enabled is false, writes are not queued until SetEnabled enables them.

func (*Store) Backfill

func (s *Store) Backfill(
	ctx context.Context,
	target string,
	list func(ctx context.Context) ([]*block.BlockRef, error),
) error

Backfill queues every block list names for upload to target, unless a backfill for target already completed. Call it after enabling uploads for target, so the backfill and new writes together cover every block.

A block the local store does not hold is skipped. The completed target is recorded durably, so an interrupted backfill runs again on the next call.

func (*Store) Evict

func (s *Store) Evict(
	ctx context.Context,
	remote block.StoreOps,
	maxBytes int64,
	keep func(*hash.Hash) bool,
) (EvictResult, error)

Evict runs one eviction pass, one at a time: it advances the epoch, then walks the queue oldest epoch first and drops local values until it has dropped maxBytes or reaches the new epoch. A block keep reports is queued at the new epoch instead. A nil keep keeps nothing.

A block leaves the local values only while no marker awaits its upload and remote reports holding it, so the remote store always holds what was dropped. An entry whose value is already gone, such as a block the garbage collector swept, is deleted. Values are dropped before their entries, so an interrupted pass leaves only entries the next pass deletes. The pass takes no lock a write waits on, since asking remote can wait on the network.

The volume shares values by hash across its block stores. Eviction relies on each placed store sealing its blocks with its own transform keys, so no other store holds the same hash.

func (*Store) GetStatus

func (s *Store) GetStatus() (Status, <-chan struct{})

GetStatus returns the upload status and a channel closed when it changes.

func (*Store) GetStoreParts

func (s *Store) GetStoreParts() []block.StorePart

GetStoreParts returns the local store that holds every block.

func (*Store) Refill

func (s *Store) Refill(ctx context.Context, ref *block.BlockRef, stored *block.StoredBlock) error

Refill writes a block read back from the remote store into the local values and queues it for eviction at the current epoch. It changes no ownership, so call it only for a block the reference graph still tracks.

func (*Store) SetEnabled

func (s *Store) SetEnabled(ctx context.Context, enabled bool) error

SetEnabled starts or stops queueing writes for upload.

Disabling drops the queued markers, the eviction queue and the backfill target: the remote store no longer needs the markers, and the local store must keep the blocks it holds.

func (*Store) SetError

func (s *Store) SetError(err error)

SetError records an upload failure in the status, such as a remote store that cannot be opened. The next successful batch clears it.

func (*Store) SetPolicy

func (s *Store) SetPolicy(policy Policy)

SetPolicy sets when queued blocks upload and the resident budget, waking Upload and budget watchers to apply it.

func (*Store) Upload

func (s *Store) Upload(ctx context.Context, remote block.StoreOps) error

Upload drains the markers to remote, oldest first, until ctx is canceled. A marker uploads once it is older than the policy's settle age, or earlier while the queue exceeds its byte limit.

Returns the first upload failure, which stays in the status until the next successful batch. The caller retries with its own backoff.

Jump to

Keyboard shortcuts

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