s3db

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 26, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultRegion is the default AWS region for s3db
	DefaultRegion = "us-east-1"

	// DefaultService is the service name for s3db signing
	DefaultService = "s3db"
)

Variables

View Source
var (
	ErrKeyNotFound = fmt.Errorf("key not found")
)

Errors

View Source
var (
	ErrNotLeader = fmt.Errorf("not the leader")
)

Errors

Functions

func CanonicalQueryString

func CanonicalQueryString(queryParams url.Values) string

CanonicalQueryString creates the canonical query string according to AWS specs

func GenObjectHash

func GenObjectHash(bucket string, object string) [32]byte

func SignRequest

func SignRequest(req *http.Request, accessKey, secretKey, region, service string) error

SignRequest signs an HTTP request using AWS Signature V4 Uses the auth.GenerateAuthHeaderReq function for consistency with S3 API

func UriEncode

func UriEncode(input string, encodeSlash bool) string

UriEncode follows AWS's specific requirements for canonical URI encoding

func ValidateSignatureHTTP

func ValidateSignatureHTTP(r *http.Request, credentials map[string]string, region, service string) (string, error)

ValidateSignatureHTTP validates an AWS Signature V4 authorization header for net/http Returns the access key if valid, or an error if invalid

Types

type Client

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

Client provides access to the distributed database cluster

func NewClient

func NewClient(config *ClientConfig) *Client

NewClient creates a new database client

func (*Client) AddNode

func (c *Client) AddNode(addr string)

AddNode adds a node to the client's node list

func (*Client) Delete

func (c *Client) Delete(table, key string) error

Delete removes a key from the specified table

func (*Client) Get

func (c *Client) Get(table, key string) ([]byte, error)

Get retrieves a value by key from the specified table

func (*Client) Leader

func (c *Client) Leader() (string, string, error)

Leader returns information about the current leader

func (*Client) Put

func (c *Client) Put(table, key string, value []byte) error

Put stores a key-value pair in the specified table

func (*Client) RemoveNode

func (c *Client) RemoveNode(addr string)

RemoveNode removes a node from the client's node list

func (*Client) Scan

func (c *Client) Scan(table, prefix string, limit int) ([]ScanItem, error)

Scan lists keys with optional prefix in the specified table

func (*Client) Status

func (c *Client) Status() (*StatusResponse, error)

Status returns the status of the connected node

type ClientConfig

type ClientConfig struct {
	Nodes              []string      // Initial list of node addresses
	AccessKeyID        string        // AWS-style access key ID
	SecretAccessKey    string        // AWS-style secret access key
	Region             string        // Region for signing (default: us-east-1)
	Service            string        // Service name for signing (default: s3db)
	Timeout            time.Duration // HTTP request timeout
	MaxRetries         int           // Max retries on failure
	InsecureSkipVerify bool          // Skip TLS certificate verification (for self-signed certs)
}

ClientConfig holds client configuration

func DefaultClientConfig

func DefaultClientConfig() *ClientConfig

DefaultClientConfig returns sensible defaults

type ClusterConfig

type ClusterConfig struct {
	NodeID    uint64         // This node's ID
	Nodes     []DBNodeConfig // All nodes in cluster
	DataDir   string         // Base data directory
	Bootstrap bool           // Whether to bootstrap a new cluster

	// Raft tuning
	HeartbeatTimeout   time.Duration
	ElectionTimeout    time.Duration
	CommitTimeout      time.Duration
	SnapshotInterval   time.Duration
	SnapshotThreshold  uint64
	TrailingLogs       uint64
	MaxAppendEntries   uint64
	LeaderLeaseTimeout time.Duration
}

ClusterConfig represents the full cluster configuration

func DefaultClusterConfig

func DefaultClusterConfig() *ClusterConfig

DefaultClusterConfig returns sensible defaults for a cluster

func (*ClusterConfig) GetNode

func (c *ClusterConfig) GetNode(id uint64) *DBNodeConfig

GetNode returns the node config for the given ID

func (*ClusterConfig) GetThisNode

func (c *ClusterConfig) GetThisNode() *DBNodeConfig

GetThisNode returns the config for this node

type Command

type Command struct {
	Type  CommandType `json:"type"`
	Table string      `json:"table"`
	Key   []byte      `json:"key"` // []byte for safe JSON base64 encoding of binary keys
	Value []byte      `json:"value,omitempty"`
}

Command represents a database operation that goes through Raft

type CommandType

type CommandType uint8

CommandType represents the type of operation

const (
	CommandPut CommandType = iota
	CommandDelete
)

type DBNodeConfig

type DBNodeConfig struct {
	ID              uint64 `toml:"id"`
	Host            string `toml:"host"`
	Port            int    `toml:"port"`
	RaftPort        int    `toml:"raft_port"`      // Separate port for Raft transport
	AdvertiseHost   string `toml:"advertise_host"` // Address to advertise to other nodes (defaults to Host if empty, or 127.0.0.1 if Host is 0.0.0.0)
	Path            string `toml:"path"`
	AccessKeyID     string `toml:"access_key_id"`
	SecretAccessKey string `toml:"secret_access_key"`
	Leader          bool   `toml:"leader"` // Initial bootstrap leader hint
}

DBNodeConfig represents a single database node in the cluster

func (*DBNodeConfig) HTTPAddr

func (n *DBNodeConfig) HTTPAddr() string

HTTPAddr returns the HTTP address for a node

func (*DBNodeConfig) RaftAddr

func (n *DBNodeConfig) RaftAddr() string

RaftAddr returns the Raft transport bind address for a node

func (*DBNodeConfig) RaftAdvertiseAddr

func (n *DBNodeConfig) RaftAdvertiseAddr() string

RaftAdvertiseAddr returns the address to advertise to other Raft nodes If AdvertiseHost is set, use it. If Host is 0.0.0.0, default to 127.0.0.1

type ErrorResponse

type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
	Leader  string `json:"leader,omitempty"` // Set when NotLeader error
}

ErrorResponse represents an error response

type FSM

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

FSM implements raft.FSM interface backed by Badger

func NewFSM

func NewFSM(db *badger.DB) *FSM

NewFSM creates a new FSM with the given Badger database

func (*FSM) Apply

func (f *FSM) Apply(log *raft.Log) interface{}

Apply is called once a log entry is committed by Raft It applies the command to the Badger database

func (*FSM) Get

func (f *FSM) Get(table, key string) ([]byte, error)

Get reads a value from the local store (can be stale on non-leader)

func (*FSM) Restore

func (f *FSM) Restore(rc io.ReadCloser) error

Restore restores the FSM from a snapshot

func (*FSM) Scan

func (f *FSM) Scan(table, prefix string, fn func(key string, value []byte) error) error

Scan iterates over keys with the given table and prefix

func (*FSM) Snapshot

func (f *FSM) Snapshot() (raft.FSMSnapshot, error)

Snapshot returns an FSMSnapshot for creating a point-in-time snapshot

type FSMSnapshot

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

FSMSnapshot implements raft.FSMSnapshot

func (*FSMSnapshot) Persist

func (s *FSMSnapshot) Persist(sink raft.SnapshotSink) error

Persist writes the snapshot to the given sink

func (*FSMSnapshot) Release

func (s *FSMSnapshot) Release()

Release is called when the snapshot is no longer needed

type GetResponse

type GetResponse struct {
	Table string `json:"table"`
	Key   string `json:"key"`
	Value []byte `json:"value"`
}

GetResponse represents a successful GET response

type JoinRequest

type JoinRequest struct {
	NodeID string `json:"node_id"`
	Addr   string `json:"addr"`
}

JoinRequest represents a request to join the cluster

type PutResponse

type PutResponse struct {
	Table string `json:"table"`
	Key   string `json:"key"`
	Size  int    `json:"size"`
}

PutResponse represents a successful PUT response

type RaftNode

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

RaftNode wraps Raft consensus with Badger storage

func NewRaftNode

func NewRaftNode(config *ClusterConfig) (*RaftNode, error)

NewRaftNode creates and initializes a new Raft node

func (*RaftNode) Close

func (n *RaftNode) Close() error

Close shuts down the Raft node cleanly with a timeout. The shutdown process: 1. Close transport first to stop network activity immediately 2. Attempt graceful Raft shutdown with 5s timeout 3. Close BoltDB log store 4. Close Badger FSM storage

func (*RaftNode) Delete

func (n *RaftNode) Delete(table, key string) error

Delete removes a key through Raft consensus

func (*RaftNode) Get

func (n *RaftNode) Get(table, key string) ([]byte, error)

Get reads a value from the local store Note: This may return stale data on followers. For strong consistency, use GetConsistent which forwards reads to the leader.

func (*RaftNode) IsLeader

func (n *RaftNode) IsLeader() bool

IsLeader returns true if this node is the current Raft leader

func (*RaftNode) Join

func (n *RaftNode) Join(nodeID string, addr string) error

Join adds a new node to the cluster (must be called on leader)

func (*RaftNode) LeaderAddr

func (n *RaftNode) LeaderAddr() string

LeaderAddr returns the address of the current leader

func (*RaftNode) LeaderID

func (n *RaftNode) LeaderID() string

LeaderID returns the ID of the current leader

func (*RaftNode) Leave

func (n *RaftNode) Leave() error

Leave removes this node from the cluster

func (*RaftNode) Put

func (n *RaftNode) Put(table, key string, value []byte) error

Put stores a key-value pair through Raft consensus

func (*RaftNode) Scan

func (n *RaftNode) Scan(table, prefix string, fn func(key string, value []byte) error) error

Scan iterates over keys with prefix in the given table

func (*RaftNode) Stats

func (n *RaftNode) Stats() map[string]string

Stats returns Raft statistics

func (*RaftNode) WaitForLeader

func (n *RaftNode) WaitForLeader(timeout time.Duration) error

WaitForLeader blocks until a leader is elected or timeout

type S3DB

type S3DB struct {
	Badger *badger.DB
}

func New

func New(dir string) (s3db *S3DB, err error)

DB functions

func (*S3DB) Close

func (s3db *S3DB) Close() (err error)

func (*S3DB) Delete

func (s3db *S3DB) Delete(key []byte) error

func (*S3DB) Exists

func (s3db *S3DB) Exists(key []byte) (bool, error)

func (*S3DB) Get

func (s3db *S3DB) Get(key []byte) ([]byte, error)

func (*S3DB) ListKeys

func (s3db *S3DB) ListKeys(prefix []byte) ([][]byte, error)

func (*S3DB) Scan

func (s3db *S3DB) Scan(prefix []byte, fn func(key, value []byte) error) error

Scan iterates over keys with the given prefix and calls the callback for each key-value pair

func (*S3DB) Set

func (s3db *S3DB) Set(key, value []byte) error

type ScanItem

type ScanItem struct {
	Key   string `json:"key"`
	Value []byte `json:"value"`
}

ScanItem represents a single item in scan results

type ScanResponse

type ScanResponse struct {
	Table  string     `json:"table"`
	Prefix string     `json:"prefix"`
	Count  int        `json:"count"`
	Items  []ScanItem `json:"items"`
}

ScanResponse represents scan results

type Server

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

Server provides HTTP REST API for the distributed database

func NewServer

func NewServer(config *ServerConfig) (*Server, error)

NewServer creates a new database server

func (*Server) GetRouter

func (s *Server) GetRouter() chi.Router

GetRouter returns the chi router for testing

func (*Server) IsLeader

func (s *Server) IsLeader() bool

IsLeader returns true if this node is the leader

func (*Server) Node

func (s *Server) Node() *RaftNode

Node returns the underlying Raft node

func (*Server) Shutdown

func (s *Server) Shutdown() error

Shutdown gracefully stops the server

func (*Server) Start

func (s *Server) Start() error

Start begins listening for HTTPS requests with TLS and HTTP/2 support

func (*Server) WaitForLeader

func (s *Server) WaitForLeader(timeout time.Duration) error

WaitForLeader blocks until a leader is elected

type ServerConfig

type ServerConfig struct {
	// HTTP settings
	Addr         string
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	IdleTimeout  time.Duration

	// TLS settings
	TLSCert string // Path to TLS certificate file
	TLSKey  string // Path to TLS private key file

	// Authentication - map of AccessKeyID -> SecretAccessKey
	Credentials map[string]string
	Region      string // Region for signature validation (default: us-east-1)
	Service     string // Service name for signature validation (default: s3db)

	// Cluster configuration
	ClusterConfig *ClusterConfig

	// Debug enables verbose request logging (chi middleware.Logger)
	// WARNING: Enabling this in production adds significant CPU overhead (~17%)
	Debug bool
}

ServerConfig holds server configuration

func DefaultServerConfig

func DefaultServerConfig() *ServerConfig

DefaultServerConfig returns sensible defaults

type StatusResponse

type StatusResponse struct {
	NodeID     string `json:"node_id"`
	State      string `json:"state"`
	Leader     string `json:"leader"`
	LeaderAddr string `json:"leader_addr"`
	Term       string `json:"term"`
	CommitIdx  string `json:"commit_index"`
	AppliedIdx string `json:"applied_index"`
	IsLeader   bool   `json:"is_leader"`
}

StatusResponse represents server status

Jump to

Keyboard shortcuts

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