Categorygithub.com/databeast/whatnot
modulepackage
0.8.2
Repository: https://github.com/databeast/whatnot.git
Documentation: pkg.go.dev

# README

Whatnot - an Etcd-like Distributed Locking Namespace Manager

Go Codacy Badge Go Report Card

If you like Etcd's namespace-driven notification subscription model, but have no requirements for long-term storage, then the formality of Etcetera can be dropped in favor of... Whatnot.

Whatnot is An Etcd-like Lockable Namespace Manager, allowing you to define a hierarchical namespace of keys (which may contain values), that can be locked with an expiring lease, either individually or for an entire prefix of the key path tree.

Performance is key, everything is done in-memory with no backing store or persistence. Multiple instances of your application can synchronize the data, so that persistence is perpetual so long as a single instance remains online.

Leases and Watch notifications occur in much the same way that they do with Etcd and its Go client. Set a watch on a particular element of a namespaced path and recieve notifications of events to that element, or optionally, any element beneath it. Set a lease on a path element and receieve an expiring mutex on modifications to it, and optionally any of its sub-paths.

Suggested Use Cases

Originally inspired by the Kubernetes REST API and its hierarchical ordering of resources, I wanted something similar, but with lower latency, and without storing the full resources into the system itself. I do a lot of microservices development and a key design factor in those is being able to extend out the datamodel, without having to backport it to existing, stable components every time.

Etcd's capability to arrange keys in a directory-like namespace, and apply mutex-style leases to a both a single key and its descendents appealed to me for this reason - allowing other components to extend a resource and be notified of it without other components having to know of these items specifically. Etcd's ability to subscribe ('watch') a key, and send notifications to subscribers of leases and changes to a single key or all of its children as well, was immensely useful for this design pattern.

Caching and Resource Locking are two tasks that are almost inseparable, and this is where Whatnot is intended to excel - acting as a distributed state coordinator, especially for microservice-based application architectures, where multiple elastically-scaling instances of a service exist together in coordinated deployments, and the overhead of an external service (redis, etc) to provide this functionality is an unnecessary resource overhead when all is required from these services is the coordination of state.

Why use this over [ProjectName]

Over Etcd ?

Simply put, Etcd's storage quorum functionality placed an upper limit on the number of notifications per second, and their accumulated latency, causing some notifications to be placed into a 'get around to eventually' queue. Those limitations combined with the resource requirements of Etcd were what inspired this project in the first place.

Over Redis ?

Redis gives tools to build some complex setups that resemble this, and it has close to the required speed too, but they require use of advanced commands and data modelling to approximate the same functionality. All of this places Redis on a scale larger than what I required here.

Over Consul ?

Consul, like Etcd, has the same hierarchical keyspace support, but focuses on persisting data with fairly low levels of state changes.

Discouraged Use cases

Whatnot was created with the intention of creating a specialized package that incorporates certain features of larger, more popular software projects, without the unwanted overhead of their additional featureset - hence.

Whatnot is not intended for persisting data.

Although its possible to write your own serializer to save the state of a Whatnot namespace (perhaps during application shutdown) the internal system itself is not intended to incorporate any kind of storage backend - Other software accomplishes this requirement and use pattern far better already. So although Whatnot includes support for values on keys, those values should never be the only canonical store of that value.

  • Speed is always in contention to Accuracy
  • Extremely large numbers of keys

Key Functionality

Individual Namespaces

  • Completely separate notification channels

Native Hierarchy Support

Just as with Etcd, Keys are organized into directory-like tree structures, where every key can have sub-keys.

Just as with directory paths, this gives us the concept of both Absolute Paths and Relative Paths.

Leases and Prefix Leases

Returns a native Go context.Context object and cancel() function - once you have obtained a lock, the rest of your code doesnt need to care about Whatnot, just follow regular Go patterns for working within a scope that has a deadline. Leases will forcibly unlock the corresponding element once their deadline is reached, so it is up to your code to obey that channel signal and cease any further operations that could induce race conditions.

Emphasis on lightweight operation

  • No additional infrastructure
  • No storage persistence/synchronization latency
  • No huge memory requirements
  • not intended to be used for billions of key

Emphasis on Structure and Hierarchy

  • Etcd's explicit directory-path style namespaces were a huge inspiration

Decentralized

  • Support for direct clustering between your applications instances via Gossip, Raft and gRPC

Built without storage persistence and centralization in mind.

  • Designed originally to coordinate cluster cache invalidation

Resource Management

Whatnot defaults to a highly reactive concurrency model, whereby each distinctly unique element in the namespace recieves its own dedicated routine to pass up event notifications to its parent.

# Packages

Package access provides Identity Tracking and optional Permissions management for managing and restricting namespace resources */.
No description provided by the author

# Functions

HealthHandler is an HTTP HandlerFunc to attach this to your appropriate HTTP Healthcheck Endpoint.
Healthy provides a Global HealthCheck poller with a simple yes/no response to overall subsystem health.
NewEventsMultiplexer creates a new event multiplexer that will duplicate incoming WatchEvents to multiple watcher channels.
NewNamespace creates a new Namespace Instance.
NewNamespaceManager create a top-level namespace manager, to contain multiple subscribable namespaces you probably only want to call this once, to initialize WhatNot, but who am I to tell you what your use cases are.

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

WithAcls turns on Whatnot's Access Control Management on individual Path Elements.
WithDeadlockBreak turns on Whatnot's Self-healing breaking of Mutex Deadlocks.
WithGossip enables Gossip protocol Cluster member discovery of other instances running the whatNot gRPC connector.
WithPruning turns on Whatnot's automatic pruning of Unused PathElement Tree sections after they remain unused for a given amount of time.
WithRaft enables Raft Quorum synchromization - improving cluster accuracy at a slight speed and bandwith cost.
No description provided by the author
WithTrace enables extended tracing of Resource Locking and Wait Queues.

# Structs

No description provided by the author
No description provided by the author
ElementWatchSubscription is a contract to be notified of all events on a given Path Element, and optionally all its child elements.
EventMultiplexer is a pub-sub mechanism where consumers can Register to receive messages sent to Broadcast.
LeaseContext implements Element Locking Lease control as a Context Interface object it is heavily recommend to use this as the context object for the rest of your functions lifetime to keep it in sync with the accordant lease it was generated with to enable your code to control and react to lease expiration.
Namespace provides unique namespaces for keyval trees.
NameSpaceManager provides top-level management of unique element namespaces.
PathElement is an individual section of a complete path.
PathError indicates that processing a provided path was not possible either it a not a valid path identifier, or not a path that can be resolved.
No description provided by the author
SemaphorePool is a combined semaphore for use by a PathElement and all its sub Elements.
No description provided by the author
WatchEvent describes an event on a Path Element or optionally any of its children, obtained and consumed via an ElementWatchSubscription.
WithLogger attaches a Logger to the Namespace manager allowing you to insert your own logging solution into Whatnot.

# Interfaces

Logger allows you to implement/attach your own logger.
No description provided by the author
No description provided by the author

# Type aliases

AbsolutePath is the fully-qualified path to a single PathElement from the root of the Namespace it resides in.
PathString is a string representation of all or part of a hierarchical set of resources in a namespace.
RelativePath is the path to a single PathElement relative to a single PathElement somewhere in its parent chain.
SubPath is a path element identifier akin to the directory names between path delimeters.