backend

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Register

func Register(t Type, f Factory)

Register registers a backend factory for the given type.

func SetAsyncBufferBudget added in v0.3.0

func SetAsyncBufferBudget(maxBytes int64)

SetAsyncBufferBudget sets the global cap (in bytes) on total read-ahead memory across all open buffers. 0 disables accounting (unlimited).

Types

type AsyncReadBuffer added in v0.3.0

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

AsyncReadBuffer wraps a readAtContexter and reads ahead into a ring buffer so FUSE reads pull from pre-filled memory instead of blocking on the network-backed source. This mirrors the client-side read-ahead that rclone's VFS provides over the WebDAV endpoint, which the native FUSE mount otherwise lacks.

State machine (the key difference from the earlier reverted design, which reset and refilled on every non-sequential read and thus thrashed under Plex/Jellyfin seek bursts):

  • probing: no buffer allocated, no fill goroutine work; every read is a direct passthrough to the source. Consecutive sequential reads are counted.
  • streaming: after armThreshold sustained sequential reads, the buffer is allocated (subject to the global memory budget) and a single fill goroutine reads ahead. A non-sequential read (seek) demotes back to probing, freeing the buffer and budget; read-ahead only re-arms after sequential reads resume.

A single fill goroutine is started lazily on first promotion and parked on the cond while probing, so promote/demote cycles never spawn goroutines.

func NewAsyncReadBuffer added in v0.3.0

func NewAsyncReadBuffer(ctx context.Context, src readAtContexter, bufSize int, fileSize int64, log *slog.Logger) *AsyncReadBuffer

NewAsyncReadBuffer creates an async read-ahead buffer wrapping src. The fill goroutine is started lazily on first promotion, so opening a file that is only probed (header reads) and closed never allocates the buffer or spawns a goroutine.

func (*AsyncReadBuffer) Close added in v0.3.0

func (a *AsyncReadBuffer) Close()

Close stops the fill goroutine and releases resources in a single call. It is equivalent to Shutdown followed by Wait. Callers that own the underlying source should prefer Shutdown → close source → Wait so an in-flight source read is unblocked promptly; Close on its own relies on the bounded safety-net timeout when a source read is wedged.

func (*AsyncReadBuffer) GetBufferedOffset added in v0.3.0

func (a *AsyncReadBuffer) GetBufferedOffset() int64

GetBufferedOffset returns the file offset up to which data is currently buffered (baseOff+filled), or 0 when probing.

func (*AsyncReadBuffer) ReadAtContext added in v0.3.0

func (a *AsyncReadBuffer) ReadAtContext(ctx context.Context, p []byte, off int64) (int, error)

ReadAtContext serves a read at the given absolute offset. Sequential reads in streaming mode are served from the ring buffer; everything else is a direct passthrough to the source while the sequential-run counter decides whether to (re)arm read-ahead.

func (*AsyncReadBuffer) Shutdown added in v0.3.0

func (a *AsyncReadBuffer) Shutdown()

Shutdown signals the fill goroutine to stop without waiting for it to exit. It cancels the buffer's context and marks the buffer closed so the goroutine exits at its next lock acquisition without issuing another source read.

Shutdown does NOT close the underlying source — the FUSE handle owns that lifecycle. Because a sequential source read blocks on the source's own context (not this buffer's), the caller MUST close/interrupt the source between Shutdown and Wait; otherwise an in-flight read cannot be unblocked and Wait falls back to its bounded safety-net timeout. Idempotent.

func (*AsyncReadBuffer) Wait added in v0.3.0

func (a *AsyncReadBuffer) Wait()

Wait drains the fill goroutine and releases resources. It must be called after Shutdown (and after the underlying source has been closed/interrupted) so the goroutine exits promptly. The bounded wait is a safety net against a wedged source: with the source interrupted first it returns near-instantly. Idempotent.

type Backend

type Backend interface {
	// Mount starts the FUSE filesystem. Blocks until unmount.
	// onReady is called once the kernel mount is confirmed live.
	Mount(ctx context.Context, onReady func()) error

	// Unmount gracefully unmounts the filesystem.
	Unmount() error

	// ForceUnmount attempts platform-specific force unmount.
	ForceUnmount() error

	// Type returns the backend type.
	Type() Type
}

Backend abstracts FUSE mount/unmount operations.

func Create

func Create(t Type, cfg Config) (Backend, error)

Create creates a backend of the given type.

type Config

type Config struct {
	MountPoint    string
	NzbFs         *nzbfilesystem.NzbFilesystem
	FuseConfig    config.FuseConfig
	StreamTracker StreamTracker
	UID           uint32
	GID           uint32
}

Config holds parameters common to all backends.

type Factory

type Factory func(cfg Config) (Backend, error)

Factory creates a Backend from a Config.

type Refresher

type Refresher interface {
	RefreshDirectory(name string)
}

Refresher is optionally implemented by backends that support kernel cache invalidation (e.g. hanwen via NotifyContent/NotifyEntry).

type StreamTracker

type StreamTracker interface {
	AddStream(filePath, source, userName, clientIP, userAgent string, totalSize int64) *nzbfilesystem.ActiveStream
	UpdateProgress(id string, bytesRead int64)
	Remove(id string)
}

StreamTracker is the subset of stream tracking needed by FUSE backends.

type Type

type Type string

Type identifies a FUSE backend implementation.

const (
	Hanwen Type = "hanwen"
	Cgo    Type = "cgo"
)

func DefaultType

func DefaultType() Type

DefaultType returns the platform-default backend type. Linux uses hanwen (pure Go). macOS uses cgo (Fuse-T). Windows FUSE support via WinFsp requires a native Windows build; cross-compiled Windows binaries default to cgo but FUSE mounting is not supported without WinFsp. Override with ALTMOUNT_FUSE_BACKEND env var (checked by caller).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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