blackboards

package
v0.2.6 Latest Latest
Warning

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

Go to latest
Published: Feb 13, 2025 License: BSD-2-Clause, Unlicense Imports: 31 Imported by: 0

Documentation

Overview

An autorunning blackboard inspects CreateAgent messages to ensure they are assigned to runners. If not, they are assigned a runner.

The blackboard tracks runners using

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Halt added in v0.2.6

func Halt(bb CoreBlackboard)

func Latency

func Latency(m *core.Message) time.Duration

Latency calculates the duration between a Message being sent and being received.

func Log added in v0.2.6

func Log(bb CoreBlackboard, sev core.Log_Severity, msg string)

func NewObjectStoreBlackboard added in v0.2.6

func NewObjectStoreBlackboard(b CoreBlackboard) *objectStoreBlackboard

func PadToWidth

func PadToWidth(s string, width int, alignment Alignment) string

PadToWidth adds padding to a string with a specified alignment.

func Ping added in v0.2.6

func Ping(bb CoreBlackboard)

func PrettyTruncateString

func PrettyTruncateString(s string, length_limit int) string

PrettyTruncateString truncates strings to a specified limit.

func RandomPick added in v0.2.6

func RandomPick(m map[string]struct{}) string

func TerminalString

func TerminalString(m *core.Message) string

TerminalString encodes a Message as a terminal string.

Types

type Alignment

type Alignment int

Alignment is a type alias of int for enumeration purposes.

const (
	AlignLeft Alignment = iota
	AlignCenter
	AlignRight
)

type AutorunBlackboard added in v0.2.6

type AutorunBlackboard struct {
	CoreBlackboard
	*RunnerPool
	// contains filtered or unexported fields
}

Autorun Blackboard does two tasks:

1. If no runners are started, it will start a default runner. 2. When a CreateAgent messages is received without a runner pre-specified, it will assign one from its list of runners.

func NewAutorunBlackboard added in v0.2.6

func NewAutorunBlackboard(bb CoreBlackboard) *AutorunBlackboard

func (*AutorunBlackboard) Len added in v0.2.6

func (a *AutorunBlackboard) Len() int

func (*AutorunBlackboard) Write added in v0.2.6

func (a *AutorunBlackboard) Write(msg *core.Message) error

Intercept messages that don't specify a runner and add one Possible additional functionality: (1) assign runner based fuzzy name matching (i.e. blackboard as a resource manager, pooling runners based on prefix or something) (2)

type Blackboard

type Blackboard interface {
	Read(msg_idx int) (*core.Message, error)
	Write(msg *core.Message) error
	Slice(start_idx, end_idx int) ([]*core.Message, error)
	Trace(msg_idx int, depth int) ([]*core.Message, error)
	Len() int
}

Blackboard is the interface that groups methods necessary for bare-bones blackboard-agent communication.

Read retrieves a single Message with a specified index.

Write attempts to write a single Message to a Blackboard.

Slice retrieves a Message slice between two indices. Slice can support reverse indexing (ala python).

Trace returns a slice of Messages that can be traced back to a Message at the specified index.

Len retrieves the length of the Blackboard message log.

func NewRedisBlackboard

func NewRedisBlackboard() Blackboard

NewRedisBlackboard

type CoreBlackboard added in v0.2.6

type CoreBlackboard interface {
	StreamingBlackboard

	// Name() returns a reasonable value to be inserted into the "source" field
	// for the methods found below
	Name() string

	// ShutdownDelay() must return the amount of time between "Warn" and "Shutdown"
	// Can be zero
	ShutdownDelay() time.Duration

	// Warn can be used to post any messages to warn users of incoming
	// shutdown and perform any preparatory tasks prior to any actual
	// blackboard shutdown
	Warn()

	// Shutdown is reserved for offline cleanup tasks only. No
	// additional messaging
	Shutdown()
}

To keep implementations simple and consistent, we'd recommend that any blackboard implementations should naively write any data they are given and allow other processes to do any validation, size-checking etc. One such construct is a wrapper blackboard, such as we've provided in core_blackboard.go, which wraps an underlying memory blackboard with a layer that performs our "cognitive" data stripping. Because we've just utilized the same interface, with a special implementation of Write, we can perform middleware-style operations.

A CoreBlackboard is our recommended "application" functionality. Using the CoreBlackboard interface allows a blackboard to be utilized in the `core` command line applications under "StartServer" (start_server.go).

type MemoryBB

type MemoryBB struct {
	Messages []*core.Message `json:"Messages"`
	Results  []*core.Message `json:"Results"`
	// contains filtered or unexported fields
}

MemoryBB is an implementation of Blackboard that is backed by memory.

func NewMemoryBB

func NewMemoryBB(ctx context.Context) *MemoryBB

NewMemoryBB creates a new MemoryBB and passes an ObjectStore to it.

func (*MemoryBB) Len

func (b *MemoryBB) Len() int

Len retrieves the MemoryBB length.

func (*MemoryBB) Name added in v0.2.6

func (b *MemoryBB) Name() string

Fufill the CoreBlackboard interface

func (*MemoryBB) ObjectStore added in v0.2.6

func (r *MemoryBB) ObjectStore() ObjectStore

func (*MemoryBB) Read

func (b *MemoryBB) Read(msg_idx int) (*core.Message, error)

Read attempts to read a single message from the MemoryBB.

func (*MemoryBB) ResultSizeLimit

func (b *MemoryBB) ResultSizeLimit() int

ResultSizeLimit specifies a limit (in MB) for a result to be stored in memory.

func (*MemoryBB) Save

func (b *MemoryBB) Save(output_file string) error

Save writes the MemoryBB event log to a JSON file.

func (*MemoryBB) Shutdown

func (b *MemoryBB) Shutdown()

Shutdown shuts the MemoryBB down and attempts to save the blackboard event log to a file.

func (*MemoryBB) ShutdownDelay added in v0.2.6

func (r *MemoryBB) ShutdownDelay() time.Duration

func (*MemoryBB) Slice

func (b *MemoryBB) Slice(start_idx, end_idx int) ([]*core.Message, error)

Slice reads multiple messages from the blackboard

We will always "read" and return messages "right to left" from start_idx to end_idx. This can loop over the end of the array. If reverse order is required, that should be done by the agent.

We support negative indexing such as python employs (-1 corresponds the final element of the array, -2 next to last, etc.)

Examples:

Read a "normal" slice:

b.Slice(25, 30) // returns messages 25, 26, 27, 28, 29
b.Slice(0, 33)  // returns first 32 messages on the blackboard

Read from message 37 to the end of the blackboard:

b.Slice(37, 0)

Read the last 5 elements the array:

b.Slice(-5, 0) // returns len(-5), len(-4), len(-3), len(-2), len(-1)

func (*MemoryBB) Stream added in v0.2.6

func (b *MemoryBB) Stream() *Stream

func (*MemoryBB) Trace

func (b *MemoryBB) Trace(msg_idx int, depth int) ([]*core.Message, error)

Trace attempts to find a trace of messages on the MemoryBB.

Tracing is the key function the core Blackboard provides (beyond essentially just a research-focused event backbone).

func (*MemoryBB) Warn added in v0.2.6

func (r *MemoryBB) Warn()

func (*MemoryBB) Write

func (b *MemoryBB) Write(msg *core.Message) error

Write attempts to write a single Message to the MemoryBB.

type MessageStringJSON

type MessageStringJSON struct {
	JSONMessage []byte `bson:"json_message"`
}

MessageStringJSON is a structure for unmarshaling BSON.

type MongoBB

type MongoBB struct {
	Spec       *MongoBBSpec
	Database   *mongo.Database
	Collection *mongo.Collection
	// contains filtered or unexported fields
}

MongoBB is an implementation of Blackboard backed by MongoDB.

func NewMongoBB

func NewMongoBB(spec *MongoBBSpec) *MongoBB

NewMongoBB creates a MongoBB from a spec.

func (*MongoBB) GetMessage

func (m *MongoBB) GetMessage(n int) (*core.Message, error)

func (*MongoBB) GetMessages

func (m *MongoBB) GetMessages(starting_at int, filter_pings bool) ([]*core.Message, error)

func (*MongoBB) GetMessagesFromEnd

func (m *MongoBB) GetMessagesFromEnd(num_messages int, filter_pings bool) ([]*core.Message, error)

TODO: DEPRECATE THESE MEMBER FUNCTIONS

func (*MongoBB) GetResults

func (m *MongoBB) GetResults(starting_at int) ([]*core.Message, error)

func (*MongoBB) Len

func (m *MongoBB) Len() int

Len retrieves the MongoBB length.

func (*MongoBB) Read

func (m *MongoBB) Read(msg_idx int) (*core.Message, error)

Read attempts to read a single message from the MongoBB.

func (*MongoBB) ResultSizeLimit

func (m *MongoBB) ResultSizeLimit() int

ResultSizeLimit specifies a limit (in MB) for a result to be stored in BSON.

func (*MongoBB) Shutdown

func (m *MongoBB) Shutdown()

Shutdown shuts the MongoBB down.

func (*MongoBB) Slice

func (m *MongoBB) Slice(start_idx, end_idx int) ([]*core.Message, error)

Read multiple messages from the blackboard

We will always "read" and return messages "right to left" from start_idx to end_idx. This can loop over the end of the array. If reverse order is required, that should be done by the agent.

We support negative indexing such as python employs (-1 corresponds the final element of the array, -2 next to last, etc.)

func (*MongoBB) Trace

func (m *MongoBB) Trace(msg_idx int, depth int) ([]*core.Message, error)

Trace attempts to find a trace of messages on the MongoBB.

Tracing is the key function the core Blackboard provides (beyond essentially just a research-focused event backbone).

func (*MongoBB) Write

func (m *MongoBB) Write(msg *core.Message) error

Write attempts to write a single Message to the MongoBB.

func (*MongoBB) WriteMessage

func (m *MongoBB) WriteMessage(msg *core.Message) error

type MongoBBSpec

type MongoBBSpec struct {
	Addr           string `yaml:"addr"`
	DatabaseName   string `yaml:"database"`
	CollectionName string `yaml:"collection"`
	Username       string `yaml:"username"`
	Password       string `yaml:"password"`
}

Playing around with the idea of a Blackboard spec here. Right now, only the Mongo implementation of the Blackboard needs a spec to function properly.

func DefaultMongoBBSpec

func DefaultMongoBBSpec() *MongoBBSpec

TODO: Implement some sort of Default spec in case a user doesn't want to specify one themselves. It would be nice if we could automatically launch a Docker container with Mongo running locally, but that'll take a little more engineering... Right now, we are going to force a user to provide a valid spec if they want to use MongoBB.

func NewMongoBBSpec

func NewMongoBBSpec(path string) *MongoBBSpec

func (*MongoBBSpec) ValidateSpec

func (s *MongoBBSpec) ValidateSpec()

Deal with potentially empty fields in spec

type ObjectStore

type ObjectStore interface {
	Put(object []byte) (string, error)
}

ObjectStore wraps the Put method, in which we upload data to the ObjectStore and receive a link that can be used to retrieve the data later. TODO: Return a url.URL instead? In some ways, string is more tolerant of possible future cleverness (i.e. resolving resourceso)

type ObjectStoreBlackboard added in v0.2.6

type ObjectStoreBlackboard interface {
	// A core blackboard is required to at least fulfill the object store interface.
	// We believe strongly that an optimized object store, offloaded from the blackboard, will be a key
	// component to this architecture to make it viable.  It's not necessarily
	// a requirement for the concept of a blackboard, more of an affordance to the
	// limitations of network infrastructure at the moment.
	//
	// The intent behind forcing a possible implementor or user to consider
	// this (including the core development team) is to eventually force a conversation about efficiency, hosting
	// and deployment, without burdening them too quickly.  We can make an
	// easy "get up and running" choice for them and/or provide a few sane
	// defaults, but eventually they should branch this object store off
	// into a different piece of infrastructure.
	//
	// Also, returning nil and just increasing the configured object store limit
	// is also perfectly valid and (one day) would be no issue for us
	// to handle if we wanted to, however it will likely always be much more efficiency
	//
	// TODO: In the long run, using the blackboard as an introduction point for
	// peer-to-peer exchanges would be the best solution @jgenender
	//
	// Also, P2P is trivial if we assume a trusted network... should we??
	ObjectStore() ObjectStore
}

type RedisBlackboard

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

RedisBlackboard is an implementation of Blackboard backed by Redis.

func (*RedisBlackboard) Len

func (r *RedisBlackboard) Len() int

func (*RedisBlackboard) Read

func (r *RedisBlackboard) Read(int) (*core.Message, error)

func (*RedisBlackboard) Shutdown

func (r *RedisBlackboard) Shutdown()

func (*RedisBlackboard) Slice

func (r *RedisBlackboard) Slice(int, int) ([]*core.Message, error)

func (*RedisBlackboard) Trace

func (r *RedisBlackboard) Trace(int, int) ([]*core.Message, error)

func (*RedisBlackboard) Write

func (r *RedisBlackboard) Write(*core.Message) error

type ReflectionBlackboard added in v0.2.6

type ReflectionBlackboard struct {
	*sync.Mutex
	// contains filtered or unexported fields
}

ReflectionBlackboard stores no data, and "reflects" all data to currently connected clients. This type of blackboard does not support meaningful tracing or polling.

This is among the "simple as possible" blackboards, and thus is intentionally feature-light.

func NewReflectionBlackboard added in v0.2.6

func NewReflectionBlackboard(ctx context.Context) *ReflectionBlackboard

func (*ReflectionBlackboard) Len added in v0.2.6

func (r *ReflectionBlackboard) Len() int

func (*ReflectionBlackboard) Name added in v0.2.6

func (r *ReflectionBlackboard) Name() string

func (*ReflectionBlackboard) ObjectStore added in v0.2.6

func (r *ReflectionBlackboard) ObjectStore() ObjectStore

func (*ReflectionBlackboard) Read added in v0.2.6

func (r *ReflectionBlackboard) Read(idx int) (*core.Message, error)

func (*ReflectionBlackboard) Shutdown added in v0.2.6

func (r *ReflectionBlackboard) Shutdown()

func (*ReflectionBlackboard) ShutdownDelay added in v0.2.6

func (r *ReflectionBlackboard) ShutdownDelay() time.Duration

func (*ReflectionBlackboard) Slice added in v0.2.6

func (r *ReflectionBlackboard) Slice(s_idx, e_idx int) ([]*core.Message, error)

func (*ReflectionBlackboard) Stream added in v0.2.6

func (r *ReflectionBlackboard) Stream() *Stream

func (*ReflectionBlackboard) Trace added in v0.2.6

func (r *ReflectionBlackboard) Trace(s_idx, e_idx int) ([]*core.Message, error)

func (*ReflectionBlackboard) Warn added in v0.2.6

func (r *ReflectionBlackboard) Warn()

Fulfill the clean CleanLifecycleBlackboard interface

func (*ReflectionBlackboard) Write added in v0.2.6

func (r *ReflectionBlackboard) Write(msg *core.Message) error

With this implementation, there is no means to get feedback on whether or not the stream can be cleaned up. NOTE: no self-referential calls b/c of the mutex. Need a better way to do this (like processing a queue)

type RunnerPool added in v0.2.6

type RunnerPool struct {
	*sync.Mutex
	// contains filtered or unexported fields
}

We just put agents in touch with runners, so all we track is the name We can support different matching schemes

func (*RunnerPool) Len added in v0.2.6

func (r *RunnerPool) Len() int

func (*RunnerPool) Match added in v0.2.6

func (r *RunnerPool) Match(runner_request string) string

Runner request is just the data that was put through

type ShutdownOnHaltBlackboard added in v0.2.6

type ShutdownOnHaltBlackboard struct {
	CoreBlackboard
	// contains filtered or unexported fields
}

func NewShutdownOnHaltBlackboard added in v0.2.6

func NewShutdownOnHaltBlackboard(bb CoreBlackboard, ch chan os.Signal) *ShutdownOnHaltBlackboard

func (*ShutdownOnHaltBlackboard) Write added in v0.2.6

func (s *ShutdownOnHaltBlackboard) Write(msg *core.Message) error

type SimpleObjectService

type SimpleObjectService struct {
	*obj.ObjectStoreServer
	// contains filtered or unexported fields
}

SimpleObjectService is an implementation of ObjectStore that embeds an ObjectStoreServer.

func NewSimpleObjectService

func NewSimpleObjectService() *SimpleObjectService

NewSimpleObjectService returns a ready, but not started, ObjectStoreService.

func StartSimpleObjectService

func StartSimpleObjectService(bind_addr, access_addr string) (*SimpleObjectService, error)

StartSimpleObjectService returns a running ObjectStoreService. WARN: Current assumption is that no one wants to/needs to customize the object bind addresses. We basically just want to get something minimal running.

TODO: Make the object store bind host settable/customizable HIGH PRIORITY

func (*SimpleObjectService) Put

func (sos *SimpleObjectService) Put(data []byte) (string, error)

Put PUTS data to the ObjectStore and returns a link to GET the data.

type Stream added in v0.2.6

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

A class that allows for the downstream reader of a channel to signal that it is done listening

func NewStream added in v0.2.6

func NewStream() *Stream

func (*Stream) Chan added in v0.2.6

func (s *Stream) Chan() <-chan *core.Message

func (*Stream) Close added in v0.2.6

func (s *Stream) Close()

func (*Stream) Closed added in v0.2.6

func (s *Stream) Closed() bool

type StreamingBlackboard added in v0.2.6

type StreamingBlackboard interface {
	Blackboard
	// Stream() chan *core.Message
	Stream() *Stream
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳