core

package
v0.0.0-...-0183129 Latest Latest
Warning

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

Go to latest
Published: May 25, 2021 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const (

	// ALLSEV means any severities.
	ANYSEV = SEVMASK

	// ANYORI means any "origin".
	ANYORI = ORIMASK

	// ANYCOMP means any component.
	ANYCOMP = COMPMASK

	// NOTHING is a mask that should result in no logs.
	NOTHING LogLevel = 0x0
	// EVERYTHING is a mask that should result in logging everything.
	EVERYTHING LogLevel = ^NOTHING

	// UERR is a user "error".
	UERR = ERROR | USR
	// APERR is an application "error".
	APERR = ERROR | APP

	// ANYINFO logs anything at or above the INFO level.  Also
	// logs all timers.
	ANYINFO = TIMER | CRIT | ERROR | WARN | INFO | ANYORI | ANYCOMP

	// ANYWARN logs anything at or about the WARN level.
	ANYWARN = CRIT | ERROR | WARN | ANYORI | ANYCOMP
)
View Source
const (
	// InjectIdAtWrite will add KW_id:id to every asserted fact.
	InjectIdAtWrite = iota

	// InjectIdNever will skip id injection of any kind.
	InjectIdNever
)
View Source
const KW_DeleteWith = "deleteWith"
View Source
const KW_id = "_id"

KW_id is the property for an injected id.

View Source
const (
	// The log record property given to the first string arg to
	// Log().
	LogKeyOp = "op"
)
View Source
const Version = "0.0.1"

Version is the Core version.

Variables

View Source
var (
	// AllowPropertyVariables enables the experimental support for a property
	// variable in a pattern that contains only one property.  See
	// github.com/Comcast/sheens/match for more details.
	AllowPropertyVariables = true
	// CheckForBadPropertyVariables runs a test to verify that a pattern does
	// not contain a property variable along with other properties.  See
	// github.com/Comcast/sheens/match for more details.
	CheckForBadPropertyVariables = true

	// DefaultMatcher is the Matcher used by the core package.
	DefaultMatcher = Matcher(CastMatcher{SheensMatcher{&match.Matcher{
		AllowPropertyVariables:       AllowPropertyVariables,
		CheckForBadPropertyVariables: CheckForBadPropertyVariables,
		Inequalities:                 true,
	}}})
)
View Source
var AlwaysHaveRule = true

AlwaysHaveRule is a hack to disable Location.Have(), which doesn't work when we're dealing with a parent rule.

View Source
var AnIpAddress = IpAddress()

AnIpAddress is maybe an IP address for this machine.

Will try to find a non-loopback interface. Failing that, it's 127.0.0.1.

View Source
var AncestorLoop = errors.New("ancestor loop detected")
View Source
var CPULoadProbe = ProbeTTL(func() (float64, error) {
	min1, _, _, err := CPULoad()
	return min1, err
}, 1*time.Second)

CPULoadProbe is a CPULoad probe for the 1-minute load average with a 1s TTL cache.

View Source
var Complete = &Condition{"complete", "complete"}
View Source
var DefaultVerbosity = ANYWARN
View Source
var HTTPBreakers = make(map[string]*OutboundBreaker)

HTTPBreakers maps URLs and hosts to OutboundBreakers for HTTPRequests (below).

This state isn't mutexified or atomic. ToDo: Or just set before doing any work.

View Source
var HTTPClientCache = NewCache(SystemParameters.HTTPClientCacheSize,
	SystemParameters.HTTPClientCacheTTL)

HTTPClientCache is a cache for http.Clients.

The need arises due to a caller's potential wish to specify settings that are associated with, say, a http.Transport as opposed to a http.Request. We very much (usually) want to cache/reuse http.Clients but we also want to allow users to specify, say, ResponseHeaderTimeouts.

So we have http.client cache that is keyed by our HTTPClientSpecs, which includes http.Transport-level (and other) settings.

This cache is an LRU cached implemented using github.com/hashicorp/golang-lru. The parameters for the cache are SystemParameters.HTTPClientCacheSize and SystemParameters.HTTPClientCacheTTL.

View Source
var Halt = errors.New("halt")
View Source
var IncCounterBase = uint64(0)

IncCounterBase is the state for IncCounter().

View Source
var JavascriptTestValue interface{}

JavascriptTestValue is returned by the Javascript function "testWithSystemParam".

Motivation: A simple test of retrying an action that failed initially. Example: Set JavascriptTestValue to something that'll cause a problem in an action. Submit an event to trigger the action, which fails. Change JavascriptTestValue to something agreeable. Re-attempt the event work and celebrate sweet victory.

View Source
var LogFormatFromEnv = os.Getenv("RULES_LOGS")
View Source
var NoContext = &Context{}

var NoContext = &Context{Context: context.NewContext()}

View Source
var NoLocationProvider = errors.New("no location provider")
View Source
var NoTimer = Timer{nil, 0, "ignore", 0, 0, false}
View Source
var Nothing = struct{}{}

Nothing really is nothing.

View Source
var SlurpCache = NewCache(SystemParameters.SlurpCacheSize, SystemParameters.SlurpCacheTTL)
View Source
var SystemParameterHooks = make([]func(*Parameters) error, 0, 0)
View Source
var SystemParameters = SetParameters(DefaultParameters())

SystemParameters packages up misc almost const parameters that the entire process will use.

ToDo: Probably make accessors for this pointer.

ToDoLater: Demote to a field in a higher-level struct somewhere?

View Source
var ThrottleExhausted = &Condition{"throttle attempts exhausted", "ephemeral"}

ThrottleExhausted is a non-fatal condition that occurs if submission used all of its attempts without success.

View Source
var ThrottleOverflow = &Condition{"throttle overflow", "ephemeral"}

ThrottleOverflow is a non-fatal condition that occurs when a submission would result in too many pending submissions.

View Source
var Throttled = errors.New("throttled")

Functions

func CPULoad

func CPULoad() (min1 float64, min5 float64, min15 float64, err error)

CPULoad gets load averages from '/proc/loadavg'.

func CachedSlurp

func CachedSlurp(ctx *Context, url string) (string, error)

CachedSlurp gets the contents (string) at a URL using a little LRU cache. The cache has a TTL of 5 seconds See the constants SlurpCacheSize and SlurpCacheTTLSecs.

func CheckErr

func CheckErr(ctx *Context, op string, err error)

CheckErr is a utility function to log an error if any.

Useful in goroutines or in other places where there is no caller to bother but something inconvenient might have occurred. Ideally, we never use this function.

func ClearTimerHistories

func ClearTimerHistories()

ClearTimerHistories resets all timer histories.

func CoerceFakeFloats

func CoerceFakeFloats(x interface{}) interface{}

CoerceFakeFloats will make ints out of floats when possible.

Since al JSON all numbers are floats, big "integers" can cause trouble. Example: millisecond timestamps get float representation: 1416505007395 becomes 1.416505007395e+12, which we don't want.

Rather than using json.Decode with UseNumber, which results in numbers of the type json.Number (which could cause trouble with reflective code), we coerce what we can outbound.

Inspirational code from Boris.

func CompileJavascript

func CompileJavascript(ctx *Context, loc *Location, libraries []string, code string) (*otto.Script, error)

compileJavascript compiles a code with specified libraries

func Copy

func Copy(x interface{}) interface{}

Copy mostly provides a deep copy of maps.

func DecodeString

func DecodeString(encoding, code string) (string, error)

func Expire

func Expire(ctx *Context, s State, id string, fact map[string]interface{}, now int64) (bool, error)

func ExtractTerms

func ExtractTerms(ctx *Context, fact map[string]interface{}) []string

ExtractTerms gets the terms from the given fact (or pattern). Since our TermIndex currently uses hash tables, it cannot do searches based on prefixes. Therefore, we extract all atomic terms without regard to structure.

See the Elasticsearch FDS in another repo. That FDS uses Lucene's B*trees ordering to do prefix-based searches. If we are using such an FDS, we could extract terms with structure such as 'a.b.c' from {"a":{"b":"c"}}. We went to a fair amount of trouble to do that previously, and we might want to reimplement this FDS to provide support for searches based on term prefixes. Shouldn't be a huge deal.

We might want to skip certain terms here that will have little value. Large numbers are candidates. Will a large number really help to find facts? We don't want an unbounded number of terms anyway, so numbers are suspect.

func GenId

func GenId(ctx *Context, fact map[string]interface{}, def string) (string, error)

GenId generates, if necessary, and id suitablef or the given fact.

If the fact is a property, then the id will be canonical. Otherwise, if 'def' is empty, a random id is generated. Otherwise, 'def' is returned. An error can occur if a call to 'parseProp' returns an error.

func GenerateUpdateTimestamp

func GenerateUpdateTimestamp(ctx *Context) string

GenerateUpdateTimestamp returns a string consisting of the current timestamp and 'AnIpAddress'.

Used by 'Update()'.

func GetCode

func GetCode(x interface{}) (string, error)

GetCode makes a single string from either a string or an array of strings.

If the given thing is an array of strings, they are joined with newlines.

If the given thing isn't a string or array of string, returns an error.

func GetProp

func GetProp(ctx *Context, s State, id string, prop string, def interface{}) (interface{}, bool, error)

GetProp is the high-level property API to get the property value for the given target id and prop.

Default value is provided by 'def'.

func GetPropString

func GetPropString(ctx *Context, s State, prop string, def string) (string, bool, error)

GetPropString is a wrapper around 'getProp' that returns a string value.

func GetRulePatterns

func GetRulePatterns(ctx *Context, rule map[string]interface{}) []map[string]interface{}

GetRulesPatterns extracts the rule's 'when' pattern.

func GetTimerNames

func GetTimerNames() []string

GetTimerNames returns a list of all know timer names.

func GetTimestamp

func GetTimestamp(ts int64) string

GetTimestamp makes a timestamp from UNIX nanoseconds.

func Gorep

func Gorep(x interface{}) string

Gorep returns a string that represents the given thing in Go -- except for plain strings.

This function is used in logging generic data. All log records should have consistent types for a given property value. If property can actually have different values, use this function to homogenize the values. This function is slow and otherwise distasteful, but perhaps it's better than nothing.

func HaveProc

func HaveProc() bool

func ISlice

func ISlice(xs interface{}) (interface{}, bool)

ISlice attempts to convert the given thing to an array of interface{}s.

If the given thing isn't array, the thing is just returned.

Uses reflection.

func IdProperty

func IdProperty(p string) bool

IdProperty returns true if the given prop starts with '!'.

func Inc

func Inc(p *uint64, d int64)

Inc atomically updates the given counter.

func IncCounter

func IncCounter() uint64

IncCounter safely returns an increasing int.

func IpAddress

func IpAddress() string

IpAddress tries to return a (non-loopback) IP address for this machine.

If it can't find one, it returns 127.0.0.1.

Exactly what this function returns is not really defined. Don't rely on it for anything important.

func IpAddresses

func IpAddresses() ([]string, error)

IpAddresses tries to find a machine's (non-loopback) network interfaces.

127.0.0.1 and ::1 are not included in the results.

Uses 'net.Interfaces()'.

func IsConstant

func IsConstant(s string) bool

func IsNakedVariable

func IsNakedVariable(s string) bool

func IsSortable

func IsSortable(xs []interface{}) bool

func IsVariable

func IsVariable(s string) bool

func LocationFunctions

func LocationFunctions(ctx *Context, loc *Location, runtime *otto.Otto, env map[string]interface{})

func Log

func Log(level LogLevel, ctx *Context, args ...interface{})

Log is the top-level API for logging everything.

'Args' should have an odd number or args. The first arg should be a string, which is typically the name of the calling function (usually qualified with the package name). The rest of the args are implement key/value pairs. The even args, which are property names, should be strings. The odd args, which are the respective values, can be anything.

If GetVerbosity() < level, then do nothing.

If the given context has a 'LogAccumulator', then 'MakeLogRecord()' is called to generate a log record that is appended to that accumulator.

func MakeLogRecord

func MakeLogRecord(args []interface{}) map[string]interface{}

MakeLogRecord is used by Log() to add log data to a context.

func Metric

func Metric(ctx *Context, args ...interface{})

func NanoStringToMilliString

func NanoStringToMilliString(ns string) string

NanoStringToMilliString drops microseconds from the string, which should be in the 'RFC3339Nano' representation.

func Now

func Now() int64

Now returns the current time in UTC nanoseconds.

func NowMicros

func NowMicros() int64

NowMicros returns the current time in UTC microseconds.

func NowSecs

func NowSecs() int64

NowSecs returns the current time in UTC seconds.

func NowString

func NowString() string

NowString returns a string representing the current time in UTC in the 'RFC3339Nano' representation.

func OneShotSchedule

func OneShotSchedule(schedule string) bool

func ParametersAddHook

func ParametersAddHook(f func(*Parameters) error)

ParametersAddHook installs a function that is called when SystemParameters change.

Not thread-safe.

func ParseJSON

func ParseJSON(ctx *Context, bs []byte) (map[string]interface{}, error)

ParseJSON parses a map from bytes.

func ParseJSONString

func ParseJSONString(ctx *Context, s string) (map[string]interface{}, error)

ParseJSONString parses a map from a string.

func Point

func Point(ctx *Context, namespace string, metric string, val interface{}, unit string, more ...string)

Point generates a log line that reports point that applications might want to monitor.

A system dashboard is a good example. This function is not a generic logging function, and it is not intended to carry much (or any) optional, fine-grained data. Instead, it's intended to be relatively robust and simple in order to make dashboard processing relatively simple. See 'tools/inload' for a rough example.

'Metric' is the label for what you are tracking. Examples: 'RuleTriggered', 'RuleTimeElapsed' (nanoseconds), 'RuleActionExecutions'.

'Val' is the numeric value. Don't use non-numeric values. Units are implicitly specified by the metric.

Ctx.app_id is added to the varargs: '"appid", Ctx.app_id'.

Example usage:

Point(ctx, "", "RuleTimeElapsed", elapsed, "Microseconds")

Log level is POINT.

If ctx.PointHook is not nil, that function is called with almost the same arguments.

This function is designed to be compatible with CloudWatch custom metrics, RRDB-style timeseries databases, and similar metrics systems.

See example PointHook in 'rulesys/main.go'.

func Post

func Post(ctx *Context, uri string, contentType string, body string) (string, error)

Post issues a POST to the specified URL.

func PrepareFact

func PrepareFact(ctx *Context, givenId string, x Map) (id string, m map[string]interface{}, err error)

func ProbeTTL

func ProbeTTL(probe func() (float64, error), ttl time.Duration) func() (float64, error)

ProbeTTL wraps a TTL cache around the given function.

func Profile

func Profile(filename string) func()

Profile starts CPU and memory profiling and returns a function that will stop that.

Writes "cpu" + filename and "mem" + filename.

Usage:

defer Profile("logfast.prof")()

func RandVar

func RandVar() string

func RandomFactsTest

func RandomFactsTest(ctx *Context, numberOfFacts int, numberOfQueries int, t *testing.T) (int64, error)

func RemProp

func RemProp(ctx *Context, s State, id string, prop string) (bool, error)

RemProp does what you'd think.

The given id is the target id.

func RuleToJSON

func RuleToJSON(ctx *Context, r Rule) ([]byte, error)

RuleToJSON generates a JSON representation of the given rule.

func RunJavascript

func RunJavascript(ctx *Context, bs *Bindings, props map[string]interface{}, src interface{}) (interface{}, error)

RunJavascript executes Javascript code with the given bindings. A new environment is created for each call. That environment contains several bindings. See http://github.com/Comcast/rulio/blob/master/doc/Manual.md#in-process-javascript-actions for details.

Currently the Javascript implementation is https://github.com/robertkrimen/otto. We might also eventually support https://code.google.com/p/v8/ .

Example
c := TestContext("ExampleRunJavascript")
bs := Bindings(map[string]interface{}{"a": 1, "b": 2})
RunJavascript(c, &bs, nil, "console.log(a+b)")
Output:

3

func SetProp

func SetProp(ctx *Context, s State, id string, prop string, val interface{}) (string, error)

SetProp is the high-level property setter.

The given id is the target id.

func Slurp

func Slurp(ctx *Context, url string) (string, error)

Slurp gets the contents (string) at a URL. Also see CachedSlurp.

func SortValues

func SortValues(vs []interface{}) ([]interface{}, error)

SortValues attempts to sort the slice generically.

func StructToMap

func StructToMap(x interface{}) (map[string]interface{}, error)

StructToMap converts a struct to a map.

func SubstituteBindings

func SubstituteBindings(ctx *Context, code string, bs Bindings) (interface{}, error)

func Timestamp

func Timestamp(t time.Time) string

Timestamp returns a string representing the given time in UTC in the 'RFC3339Nano' representation.

func UUID

func UUID() string

UUID generates what is likely a v4 UUID using data from `crypto/Reader`. If crypto/Reader fails, returns the empty string instead. The implementation is platform-dependent; see

https://golang.org/pkg/crypto/rand/ 								(random byte generation)
https://groups.google.com/forum/#!topic/golang-nuts/Rn13T6BZpgE	(uuid generation)

func UseCores

func UseCores(ctx *Context, silent bool)

UseCores will use all cores unless the environment variable 'GOMAXPROCS' is set.

If 'silent', then do not make a 'Log()' call.

There is a proposal for Go 1.5 to make GOMAXPROCS default to the number of available cores.

func ValidateId

func ValidateId(ctx, id string) error

ValidateId will return an error if the id is illegal.

The empty id is illegal, and any id starting with '!' is also illegal. An id longer that IdLengthLimit is also illegal. All other ids are (for now) legal.

func Who

func Who(skip int) string

Types

type Accumulator

type Accumulator struct {

	// Acc is the buffer.
	Acc []interface{}

	// Limit is the capacity.
	Limit int

	// Dumped is the number of entries that have been dumped to
	// make room for other entries.
	Dumped int
}

Accumulator is sliding buffer.

As it fills, older entries slide off the back.

Not synchronized.

func NewAccumulator

func NewAccumulator(limit int) *Accumulator

NewAccumulator returns an Accumulator with the given size.

func (*Accumulator) Add

func (acc *Accumulator) Add(x interface{})

Add adds the thing to the Accumulator.

If there isn't room, then room.

type Action

type Action struct {
	// Code is optional Javascript.
	//
	// Can either be an array of strings or a string.
	Code interface{} `json:"code,omitempty"`

	// Endpoint is the optional target action executor.
	Endpoint string `json:"endpoint,omitempty"`

	// Subvars controls whether bindings are injected directly
	// into the Javascript environment.
	//
	// For example, if the rule evaluation results in a binding
	// for "foo" and if Subvars is true, then the Javascript
	// variable 'foo' will be bound.
	Subvars bool `json:"subvars,omitempty"`

	// Opts is a map of generic options.
	//
	// For now, only "libraries" is used.  "libraries", if given,
	// should be an array of URLs that return Javascript.
	Opts map[string]interface{} `json:"opts,omitempty"`
}

Action is something that a rule performs.

func ActionFromMap

func ActionFromMap(ctx *Context, m map[string]interface{}) (*Action, error)

func (*Action) GetStringCode

func (a *Action) GetStringCode() (string, error)

type ActionInterpreter

type ActionInterpreter interface {
	// GetThunk returns a function that can be executed to
	// interpreter the given Action.
	GetThunk(ctx *Context, loc *Location, bs Bindings, a Action) (func() (interface{}, error), error)

	// GetName is used to find the ActionInterpreter based on an
	// Action's Endpoint (which is now a very bad name).
	GetName() string
}

ActionInterpreter can make a thunk, which can then be executed to interpret an action.

The map of available ActionInterpreters is at Location.Control.ActionInterpreters. Those keys are the Names of the ActionInterpreters.

type AddHookFn

type AddHookFn func(ctx *Context, state State, id string, fact Map, loading bool) error

type AndQuery

type AndQuery struct {
	Conjuncts []Query
}

func (AndQuery) Exec

func (a AndQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

func (AndQuery) MarshalJSON

func (q AndQuery) MarshalJSON() ([]byte, error)

type App

type App interface {
	GenerateHeaders(ctx *Context) map[string]string
	ProcessBindings(ctx *Context, bs Bindings) Bindings

	// UpdateJavascriptRuntime can be used to modify the
	// Javascript environment for actions and condition code.
	UpdateJavascriptRuntime(ctx *Context, runtime *otto.Otto) error

	// ProcessQuery can be used to replace or wrap queries when unmarshaling a
	// rule condition.  The method gets the raw generic query data along with
	// the query created by Rulio.
	ProcessQuery(ctx *Context, raw map[string]interface{}, query Query) Query
}

type Bindings

type Bindings map[string]interface{}

Bindings is a map from variables (strings starting with a '?') to their values.

func ExtendBindings

func ExtendBindings(ctx *Context, x *Bindings, y *Bindings) *Bindings

Copy the given bindings into a new set of bindings.

func Match

func Match(ctx *Context, pattern, fact interface{}, bs Bindings) ([]Bindings, error)

Match provides backwards compatibility around the Matcher interface.

func Matches

func Matches(ctx *Context, pattern, fact interface{}) ([]Bindings, error)

Matches provides backwards compatibility around the Matcher interface.

func (*Bindings) Bind

func (bs *Bindings) Bind(ctx *Context, pat interface{}) interface{}

Replace all variables in the given pattern with their bindings (when possible).

func (*Bindings) StripQuestionMarks

func (bs *Bindings) StripQuestionMarks(ctx *Context) *Bindings

Strips '?' from variables. Warn if no '?'.

type Breaker

type Breaker interface {

	// Status report the breaker load (but where 100% is
	// represented by 1.0), whether the breaker is closed (good)
	// or open (bad), whether the breaker is disabled, and any
	// error encountered getting this status.
	Status() BreakerStatus

	// Disable does what you think.
	Disable(bool)

	// Do submits work to the breaker.  The work is attempted only
	// if the breaker is closed.  If the work is attempted, any
	// resulting error is returned.
	//
	// The given function can be nil.
	Do(func() error) (attempted bool, err error)
}

Breaker is the basic interface for a simple circuit breaker.

You can get status, submit work, and disable a circuit breaker.

type BreakerStatus

type BreakerStatus struct {

	// Load is the ratio of the current count to the limit.
	Load float64

	// Closed indicates if the breaker is closed (good) or open
	// (bad).
	Closed bool

	// Disabled means that the breaker will allow everything.
	Disabled bool

	// Error is the last error encountered internally (if any).
	Error error
}

BreakerStatus is used instead of return several values from Status().

type Cache

type Cache struct {
	sync.Mutex

	TTL time.Duration
	// contains filtered or unexported fields
}

func NewCache

func NewCache(limit int, ttl time.Duration) *Cache

func (*Cache) Add

func (c *Cache) Add(key, value interface{})

Add adds a value to the cache.

func (*Cache) Get

func (c *Cache) Get(key interface{}) (value interface{}, ok bool)

Get looks up a key's value from the cache.

func (*Cache) GetWith

func (c *Cache) GetWith(key interface{}, thunk func() (interface{}, error)) (interface{}, error)

func (*Cache) Keys

func (c *Cache) Keys() []interface{}

Keys returns a slice of the keys in the cache.

func (*Cache) Len

func (c *Cache) Len() int

Len returns the number of items in the cache.

func (*Cache) Purge

func (c *Cache) Purge()

Purge is used to completely clear the cache

func (*Cache) Remove

func (c *Cache) Remove(key interface{})

Remove removes the provided key from the cache.

func (*Cache) RemoveOldest

func (c *Cache) RemoveOldest()

RemoveOldest removes the oldest item from the cache.

type CastMatcher

type CastMatcher struct {
	Matcher
}

CastMatcher is a wrapper for casting Map values to map[string]interface{}, and slices to []interface{}.

func (CastMatcher) Match

func (m CastMatcher) Match(pattern, fact interface{}, bs Bindings) ([]Bindings, error)

Match implements the Matcher interface.

type CleanAction

type CleanAction Action

func (*CleanAction) UnmarshalJSON

func (a *CleanAction) UnmarshalJSON(bs []byte) error

type CleanRule

type CleanRule Rule

func (*CleanRule) MarshalJSON

func (r *CleanRule) MarshalJSON() ([]byte, error)

func (*CleanRule) UnmarshalJSON

func (r *CleanRule) UnmarshalJSON(bs []byte) error

type CodeQuery

type CodeQuery struct {
	Code      string   `json:"code"`
	Language  string   `json:"language,omitempty"`
	Libraries []string `json:"libraries,omitempty"`
	// contains filtered or unexported fields
}

func (CodeQuery) Exec

func (c CodeQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

func (*CodeQuery) GetCompiledCode

func (c *CodeQuery) GetCompiledCode(ctx *Context, loc *Location) (interface{}, error)

type ComboBreaker

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

ComboBreaker is a bunch of Breakers considered as one.

A ComboBreaker's status is based on the worst of its constituent breaker's statuses.

func NewComboBreaker

func NewComboBreaker(bs ...Breaker) *ComboBreaker

func (*ComboBreaker) Disable

func (c *ComboBreaker) Disable(disabled bool)

func (*ComboBreaker) Do

func (c *ComboBreaker) Do(f func() error) (bool, error)

func (*ComboBreaker) Status

func (c *ComboBreaker) Status() BreakerStatus

type CommandSpec

type CommandSpec struct {
	Path    string            `json:"path"`
	Args    []string          `json:"args"`
	Dir     string            `json:"dir"`
	CGroup  string            `json:"cgroup"`
	AddEnv  map[string]string `json:"addEnv"`
	Env     map[string]string `json:"env"`
	Stdin   string            `json:"stdin"`
	Stdout  string            `json:"stdout"`
	Stderr  string            `json:"stderr"`
	Error   string            `json:",omit"`
	Success bool              `json:",success"`
	*os.ProcessState
}

func (*CommandSpec) Exec

func (cs *CommandSpec) Exec(ctx *Context) error

func (*CommandSpec) Set

func (cs *CommandSpec) Set(x interface{}) error

type Condition

type Condition struct {
	Msg string `json:"msg,omitempty"`

	Hope string `json:"status,omitempty"`
}

func (*Condition) Error

func (c *Condition) Error() string

func (*Condition) IsFatal

func (c *Condition) IsFatal() bool

func (*Condition) String

func (c *Condition) String() string

type Config

type Config struct {
}

Config are read-only, boot-time settings. Once specified, these settings cannot be changed.

type Context

type Context struct {
	context.Context
	sync.RWMutex

	Verbosity LogLevel

	// If target location.Mode.ReadKey is not nil, then this
	// ReadKey must match it in order to a read API to be allowed.
	ReadKey string

	// If target location.Mode.WriteKey is not nil, then this
	// WriteKey must match it in order to a read API to be allowed.
	WriteKey string

	// LogAccumulator, if it exists, will collect log records.
	LogAccumulator *Accumulator

	// LogAccumulatorLimit determines LogAccumulator detail.
	LogAccumulatorLevel LogLevel

	// LogHook, if not nil, is called for every log record.
	LogHook LogHook

	// PointHook, if not nil, is called from 'Point()'.
	PointHook PointHook

	// App specific behavior modifiers
	App App

	// Custom application tracing
	Tracer Tracer

	Logger Logger
	// contains filtered or unexported fields
}

func BenchContext

func BenchContext(appId string) *Context

func NewContext

func NewContext(prefix string) *Context

func TestContext

func TestContext(prefix string) *Context

func TestContextWithLocation

func TestContextWithLocation(name string) (*Context, error)

TextContextWithLocation creates a location with indexed state on memory storage. Also returns a Context with its location se.

func (*Context) AddProp

func (c *Context) AddProp(prop string, val interface{})

func (*Context) AddValue

func (c *Context) AddValue(name string, val interface{})

AddValue just exists for backwards compatibility. Just calls AddProp().

func (*Context) GetLoc

func (c *Context) GetLoc() *Location

func (*Context) Id

func (c *Context) Id() string

func (*Context) Location

func (c *Context) Location() *Location

func (*Context) Log

func (ctx *Context) Log(level LogLevel, op string, args ...interface{})

func (*Context) Prop

func (c *Context) Prop(prop string) interface{}

func (*Context) SetLoc

func (c *Context) SetLoc(loc *Location) *Location

func (*Context) SetLogValue

func (ctx *Context) SetLogValue(name string, val interface{})

func (*Context) SetValue

func (c *Context) SetValue(name string, val interface{})

SetValue just exists for backwards compatibility. Just calls AddProp().

func (*Context) StartSpan

func (ctx *Context) StartSpan(opName string) *Context

func (*Context) StopSpan

func (ctx *Context) StopSpan()

func (*Context) SubContext

func (ctx *Context) SubContext() *Context

type Control

type Control struct {
	// Turn off timer logging.
	//
	// The property is "NoTiming" to make the natural default do
	// what we usually want.  Also see 'Control.Defaults()'.
	NoTiming bool

	// Control what's logged.
	//
	// Examples: 'ANYINFO', 'ANYWARN', 'EVERYTHING', 'NOTHING'.
	// See contants defined in this file.  Also see
	// 'ParseVerbosity()'.
	Verbosity LogLevel

	// Logging format: "CSV" (one-line JSON using external logger
	// -- not comma-separated values!), "pretty" (which spews
	// pretty-printed JSON), or "none" (which doesn't emit
	// anything).  Default is "CSV".
	//
	// The environment variable 'RULES_LOGS' overrides this
	// setting, which makes it easy to do quick performance tests
	// with no logging.
	Logging string

	// The maximum number of facts this Location will store.
	MaxFacts int

	// BindingsWarningLimit sets the threshold for a warning when
	// that many bindings are found during a fact search.
	BindingsWarningLimit int

	// Run fact expiration before every search.
	ExpireFactsDuringSearch bool

	// Before returning search results, check for fact expirations.
	CheckForFactExpiration bool

	// A directory of services used for finding action endpoints
	// and external fact service endpoints.  A value is an array
	// of URLs, one of which is picked at random for cheap load
	// balancing.
	//
	// Also see InternalFactServices.
	Services map[string][]string

	// ActionInterpreters maps an action endpoint (property) to an
	// interpreter.
	ActionInterpreters map[string]ActionInterpreter

	// InternalFactServices maps logical names to FactServices
	// (that are implemented within this process).
	//
	// Also see Services.
	InternalFactServices map[string]FactService `json:"-"`

	// Libraries of Javascript code made available to in-process
	// Javascript (both in conditions and in actions).  Each value
	// should be either a URL that returns Javascript code or a
	// string of Javascript code.
	Libraries map[string]string

	// Misc props that are available to in-process Javascript
	// (in conditions and actions).
	CodeProps map[string]interface{}

	// What it says.  Value is a string that can be parsed by Go's
	// http://golang.org/pkg/time/#ParseDuration.  This value can
	// be overridden during `ingest`.
	//
	// Note the type: a 'Duration', not a 'time.Duration'.  Why?
	// Because we want to parse JSON into this struct.  See
	// 'Duration' below.
	ExternalFactServiceTimeout Duration

	// ActionTimeout (nanoseconds) greater than zero will attempt
	// to terminate any action execution that lasts longer than
	// the timeout.  Not implemented yet.
	ActionTimeout Duration

	// JavascriptTimeout (nanoseconds) non-negative will attempt
	// to terminate any action execution that lasts longer than
	// the timeout.  Zero means to use
	// System.DefaultJavascriptTimeout.
	JavascriptTimeout Duration

	// DisableExecFunction removes the 'shell' function from the
	// Javascript environment.
	DisableExecFunction bool
	// UseDefaultVariableValue will give DefaultVariableValue to
	// unbound variables.  Otherwise and unbound variable will
	// (hopefully) result in an error.
	UseDefaultVariableValue bool

	// DefaultVariableValue will be assigned to any unbound
	// variables if 'UseDefaultVariableValue' is true.
	DefaultVariableValue interface{}
}

SystemControl represents ephemeral control options.

These settings are process-specific and not stored. Note that all of these values are simple (not maps or arrays or structs). You can change them (hopefully atomically) at will.

func DefaultControl

func DefaultControl() *Control

DefaultControl makes a Control using Control.Defaults()

func (*Control) Copy

func (c *Control) Copy() *Control

Copy makes a shallow copy.

func (*Control) Defaults

func (c *Control) Defaults() *Control

Defaults sets up some reasonable values.

ToDo: Move to SystemParameters

type Counter

type Counter struct {
	sync.Mutex
	Count int
}

func NewCounter

func NewCounter(steps int) *Counter

type Duration

type Duration time.Duration

Duration allows us to parse strings into durations. See Duration.UnmarshalJSON().

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(data []byte) error

UnmarshalJSON parses a string into a Duration.

Go says, "cannot define new methods on non-local type time.Duration", so we have to work a little indirectly. Double quotes are stripped, and a string consisting entire of numbers is interpreted as nanoseconds. Otherwise the string is parsed as a Go time.Duration.

type EmptyQuery

type EmptyQuery struct {
}

func (EmptyQuery) Exec

func (p EmptyQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

type EvalRule

type EvalRule struct {
	// Rule is the target rule.
	Rule *CleanRule `json:"rule,omitempty"`

	Bindingss []Bindings `json:"bindingss,omitempty"`

	Disposition *Condition `json:"disposition,omitempty"`

	Children []*EvalRuleCondition `json:"children,omitempty"`

	DoneWork *RuleDone `json:",omitempty"`

	Parent *FindRules `json:"-"`
}

func (*EvalRule) Dispositions

func (w *EvalRule) Dispositions() []Condition

func (*EvalRule) Do

func (w *EvalRule) Do(ctx *Context, loc *Location)

type EvalRuleCondition

type EvalRuleCondition struct {
	// Bindingss from the event matched against the rule's 'when'
	// pattern.
	Bindings Bindings `json:"bindings,omitempty"`

	Disposition *Condition `json:"disposition,omitempty"`

	// Children are the ExecRuleActions for each Bindings.
	Children []*ExecRuleAction `json:"children,omitempty"`

	Parent *EvalRule `json:"-"`
}

func (*EvalRuleCondition) Do

func (w *EvalRuleCondition) Do(ctx *Context, loc *Location)

type ExecRuleAction

type ExecRuleAction struct {
	// Bindings from the combined event patching and condition
	// evaluation.
	//
	// Not "Bindingss" because we execute the action for each
	// bindings in Bindingss that resulted from the rule condition
	// evaluation.
	Bindings map[string]interface{} `json:"bindings,omitempty"`

	// Act is the action to execute.
	Act Action `json:"action,omitempty"`

	Disposition *Condition `json:"disposition,omitempty"`

	Parent *EvalRuleCondition `json:"-"`

	// Value is the result of the action execution.
	Value interface{} `json:"value,omitempty"`
}

func (*ExecRuleAction) Do

func (w *ExecRuleAction) Do(ctx *Context, loc *Location)

type ExpiredError

type ExpiredError struct {
}

func (*ExpiredError) Error

func (e *ExpiredError) Error() string

func (*ExpiredError) IsFatal

func (e *ExpiredError) IsFatal() bool

func (*ExpiredError) String

func (e *ExpiredError) String() string

type FactService

type FactService interface {
	Search(ctx *Context, pattern Map) (*SearchResults, error)
}

type FactServiceFromURI

type FactServiceFromURI struct {
	URI     string
	Timeout time.Duration
}

func (*FactServiceFromURI) Search

func (s *FactServiceFromURI) Search(ctx *Context, pattern Map) (*SearchResults, error)

type FindRules

type FindRules struct {
	// Event is the input event.
	Event map[string]interface{} `json:"event,omitempty"`

	// Disposition reports how things went.
	Disposition *Condition `json:"disposition,omitempty"`

	// Children are the EvalRuleConditions for each found rule.
	Children []*EvalRule `json:"children,omitempty"`

	Values []interface{} `json:"values"`
}

func (*FindRules) Do

func (w *FindRules) Do(ctx *Context, loc *Location)

type GenericQuery

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

func (*GenericQuery) Get

func (q *GenericQuery) Get() Query

func (*GenericQuery) MarshalJSON

func (q *GenericQuery) MarshalJSON() ([]byte, error)

func (*GenericQuery) UnmarshalJSON

func (q *GenericQuery) UnmarshalJSON(bs []byte) error

type HTTPClientSpec

type HTTPClientSpec struct {
	Timeout            Duration `json:"timeout,omitempty"`
	InsecureSkipVerify bool     `json:"insecureSkipVerify,omitempty"`

	DisableKeepAlives     bool     `json:"disableKeepAlives,omitempty"`
	ResponseHeaderTimeout Duration `json:"responseHeaderTimeout,omitempty"`
	MaxIdleConnsPerHost   int      `json:"maxIdleConnsPerHost,omitempty"`
}

HTTPClientSpec packages up all configuration for an HTTP request. This configuration includes settings such as ResponseHeaderTimeout that are below the level of Go's http.Request.

Instances of this type will serve as hash keys for the http.Client cache.

func NewHTTPClientSpec

func NewHTTPClientSpec() *HTTPClientSpec

DefaultHTTPClientSpec generates HTTPClientSpec based on defaults given by SystemParameters.

func (*HTTPClientSpec) Client

func (cs *HTTPClientSpec) Client() (*http.Client, error)

Client creates a new http.Client for the given spec.

type HTTPRequest

type HTTPRequest struct {
	// Method is the HTTP request method (e.g., "POST").
	Method string `json:"method,omitempty"`

	// URI is what you expect.
	URI string `json:"uri"`

	// Values to be add to Header for the request
	//
	// ToDo: Probably support proper []string values.
	Headers map[string]string `json:"headers,omitempty"`

	// Body is the request body.
	Body string `json:"body,omitempty"`

	// ContentType is what you expect.
	ContentType string `json:"contentType,omitempty"`

	// Env (if given) provides and receives cookies.
	Env map[string]interface{} `json:"env,omitempty"`

	// ClientSpec controls lower-level aspects of the HTTP request.
	ClientSpec *HTTPClientSpec `json:"client,omitempty"`
}

HTTPRequest packages up all data required to make an HTTP request (that can retry). Use 'NewHTTPRequest' to make one.

We no longer do/control retries here.

func NewHTTPRequest

func NewHTTPRequest(ctx *Context, method string, uri string, body string) *HTTPRequest

NewHTTPRequest generates a basic HTTPRequest using some defaults from SystemParameters.

You can customize the returned instance. For example, you can set its 'Env' to deal with cookies.

func (*HTTPRequest) Client

func (r *HTTPRequest) Client(ctx *Context) (*http.Client, error)

Client returns an http.Client appropriate for the given request.

This function first consults HTTPClientCache. If a client with a matching HTTPClientSpec exists, it's returned. Otherwise a new client is created, cached, and returned.

There is probably a race condition in this code, but I don't think we care. Famous last words.

func (HTTPRequest) Do

func (r HTTPRequest) Do(ctx *Context) (*HTTPResult, error)

func (HTTPRequest) DoOnce

func (r HTTPRequest) DoOnce(ctx *Context, t *HTTPResult) error

DoOnce get a client, constructs a request, issues the request, and gathers the result.

func (HTTPRequest) Request

func (r HTTPRequest) Request(ctx *Context) (*http.Request, error)

Request constructs but does not issue a http.Request.

If 'Env' isn't nil, that map will be used to obtain cookie data.

type HTTPResult

type HTTPResult struct {
	// Status is the last HTTP status code received.
	Status int

	// Body is the last body (if any) received.
	Body string

	// Attempts is the number of attempts made.
	Attempts int

	// Error is the most recent error message.
	//
	// We use a string here for the convenience of Javascript
	// callers.  Might be a bad idea.
	Error string

	// Headers are the response headers.
	Headers map[string][]string
}

HTTPResult packages up everything we return to the caller of an HTTPRequest.

We're trying to use only basic field types for the convenience of Javascript users.

type IndexedState

type IndexedState struct {
	sync.RWMutex

	// Name should probably the name of the location for this state.
	Name string

	// FactIndex is the in-memory term index that allows us to
	// search facts.
	FactIndex *TermIndex

	// RuleIndex is the in-memory pattern index that allows us to
	// find rules for an incoming event.
	RuleIndex *PatternIndex

	// Map from IDs to facts.
	IdToFact map[string]Map

	// Store is how we persist and load data.
	Store Storage

	// Loaded indicates whether we have loaded data from Store.
	Loaded bool
	// contains filtered or unexported fields
}

func NewIndexedState

func NewIndexedState(ctx *Context, name string, store Storage) (*IndexedState, error)

func (*IndexedState) Add

func (s *IndexedState) Add(ctx *Context, id string, x Map) (string, error)

func (*IndexedState) AddHook

func (s *IndexedState) AddHook(hook AddHookFn)

func (*IndexedState) Clear

func (s *IndexedState) Clear(ctx *Context) error

func (*IndexedState) Count

func (s *IndexedState) Count(ctx *Context) int

func (*IndexedState) Delete

func (s *IndexedState) Delete(ctx *Context) error

func (*IndexedState) FindCachedRules

func (s *IndexedState) FindCachedRules(ctx *Context, event Map) (map[string]*Rule, error)

func (*IndexedState) FindRules

func (s *IndexedState) FindRules(ctx *Context, event Map) (map[string]Map, error)

func (*IndexedState) Get

func (s *IndexedState) Get(ctx *Context, id string) (Map, error)

func (*IndexedState) IsLoaded

func (s *IndexedState) IsLoaded(ctx *Context) bool

func (*IndexedState) Load

func (s *IndexedState) Load(ctx *Context) error

func (*IndexedState) Rem

func (s *IndexedState) Rem(ctx *Context, id string) (bool, error)

func (*IndexedState) RemHook

func (s *IndexedState) RemHook(hook RemHookFn)

func (*IndexedState) Search

func (s *IndexedState) Search(ctx *Context, pattern Map) (*SearchResults, error)

Search queries the term index for the given pattern (represented as JSON). Obtains and releases the FDS mutex.

func (*IndexedState) SearchForIDs

func (s *IndexedState) SearchForIDs(ctx *Context, pattern Map) ([]string, error)

type LinearState

type LinearState struct {
	sync.RWMutex

	// Name should probably the name of the location for this state.
	Name string

	Facts map[string]RawFact
	// contains filtered or unexported fields
}

func NewLinearState

func NewLinearState(ctx *Context, name string, store Storage) (*LinearState, error)

func (*LinearState) Add

func (s *LinearState) Add(ctx *Context, id string, x Map) (string, error)

func (*LinearState) AddHook

func (s *LinearState) AddHook(hook AddHookFn)

func (*LinearState) Clear

func (s *LinearState) Clear(ctx *Context) error

func (*LinearState) Count

func (s *LinearState) Count(ctx *Context) int

Count returns an approximate count of the number of facts.

Only an approximation because we will count expired facts that have not been removed.

func (*LinearState) Delete

func (s *LinearState) Delete(ctx *Context) error

func (*LinearState) FindCachedRules

func (s *LinearState) FindCachedRules(ctx *Context, event Map) (map[string]*Rule, error)

FindCachedRules functions similarly to FindRules, except that an in-memory cache is used if a rule is not in the cache, it is added from persistence

func (*LinearState) FindRules

func (s *LinearState) FindRules(ctx *Context, event Map) (map[string]Map, error)

func (*LinearState) Get

func (s *LinearState) Get(ctx *Context, id string) (Map, error)

func (*LinearState) IsLoaded

func (s *LinearState) IsLoaded(ctx *Context) bool

func (*LinearState) Load

func (s *LinearState) Load(ctx *Context) error

func (*LinearState) Rem

func (s *LinearState) Rem(ctx *Context, id string) (bool, error)

func (*LinearState) RemHook

func (s *LinearState) RemHook(hook RemHookFn)

func (*LinearState) Search

func (s *LinearState) Search(ctx *Context, pattern Map) (*SearchResults, error)

type Location

type Location struct {
	sync.RWMutex
	Name     string
	ReadOnly bool
	Config   *Config

	// Provider is required when using parent locations.  Must be
	// set when the Location is created and then left unchanged.
	//
	// sys.System should be a good Provider.
	Provider LocationProvider
	// contains filtered or unexported fields
}

func NewLocation

func NewLocation(ctx *Context, name string, state State, ctrl *Control) (*Location, error)

func (*Location) AddFact

func (loc *Location) AddFact(ctx *Context, id string, fact Map) (string, error)

func (*Location) AddRule

func (loc *Location) AddRule(ctx *Context, id string, rule Map) (string, error)

func (*Location) AtCapacity

func (loc *Location) AtCapacity(ctx *Context) bool

func (*Location) CheckRead

func (loc *Location) CheckRead(ctx *Context) error

func (*Location) CheckWrite

func (loc *Location) CheckWrite(ctx *Context) error

func (*Location) Clear

func (loc *Location) Clear(ctx *Context) error

func (*Location) ClearStats

func (loc *Location) ClearStats()

func (*Location) Control

func (loc *Location) Control() *Control

func (*Location) Delete

func (loc *Location) Delete(ctx *Context) error

func (*Location) DoAncestors

func (loc *Location) DoAncestors(ctx *Context, fn func(*Location) error) error

DoAncestors calls the given function on this location and all of its ancestors in depth-first order.

func (*Location) EnableRule

func (loc *Location) EnableRule(ctx *Context, id string, enable bool) error

func (*Location) Enabled

func (loc *Location) Enabled(ctx *Context) bool

func (*Location) ExecAction

func (loc *Location) ExecAction(ctx *Context, bs Bindings, a Action) (interface{}, error)

func (*Location) GetFact

func (loc *Location) GetFact(ctx *Context, id string) (Map, error)

func (*Location) GetParents

func (loc *Location) GetParents(ctx *Context) ([]string, error)

GetParents does what you'd think.

Maybe shouldn't be a top-level location API. Instead expose 'GetProp' and document special properties?

func (*Location) GetProp

func (loc *Location) GetProp(ctx *Context, prop string, def interface{}) (interface{}, bool, error)

func (*Location) GetPropString

func (loc *Location) GetPropString(ctx *Context, prop string, def string) (string, bool, error)

func (*Location) GetRule

func (loc *Location) GetRule(ctx *Context, id string) (Map, error)

func (*Location) Have

func (loc *Location) Have(ctx *Context, id string, isRule bool) (bool, error)

func (*Location) IsReadOnly

func (loc *Location) IsReadOnly(ctx *Context) bool

func (*Location) ListRules

func (loc *Location) ListRules(ctx *Context, includeInherited bool) ([]string, error)

func (*Location) PrepareWork

func (loc *Location) PrepareWork(ctx *Context, event Map) (*FindRules, error)

func (*Location) ProcessEvent

func (loc *Location) ProcessEvent(ctx *Context, event Map) (*FindRules, *Condition)
Example (Basic)
previous := SystemParameters.IdInjectionTime
SystemParameters.IdInjectionTime = InjectIdNever
// Will cause much confusion and trouble with concurrent testing.
defer func() {
	SystemParameters.IdInjectionTime = previous
}()

// Keep the aeroplane in such an attitude that the air
// pressure is directly in the aviator's face.
//
//  --Horatio C. Barber, 1916

RuleTest(TestContext("ExampleRuleTest1"),
	"TestRules1",
	`
{"when":{"pattern":{"at":"?there"}},
 "condition":{"pattern":{"likes":"?what"}},
 "actions":[{"code":"console.log(\"serve \" + what + \" at \" + there);"}]}
`,
	[]string{`{"likes":"tacos"}`},
	[]string{`{"at":"home"}`})
Output:

serve tacos at home
Example (Out)
previous := SystemParameters.IdInjectionTime
SystemParameters.IdInjectionTime = InjectIdNever
// Will cause much confusion and trouble with concurrent testing.
defer func() {
	SystemParameters.IdInjectionTime = previous
}()

c := make(chan interface{})

ctx := TestContext("test")
ctx.AddValue("out", c)

go RuleTest(ctx,
	"TestRules1",
	`
{"when":{"pattern":{"at":"?there"}},
 "condition":{"pattern":{"likes":"?what"}},
 "actions":[{"code":"Env.out(\"serve \" + what + \" at \" + there);"}]}
`,
	[]string{`{"likes":"tacos"}`},
	[]string{`{"at":"home"}`})

x, _ := chanGet(c, 6*time.Second, nil)
fmt.Printf("Got: %#v\n", x)
Output:

Got: "serve tacos at home"

func (*Location) Query

func (loc *Location) Query(ctx *Context, query string) (*QueryResult, error)

func (*Location) RemFact

func (loc *Location) RemFact(ctx *Context, id string) (string, error)

func (*Location) RemProp

func (loc *Location) RemProp(ctx *Context, id string, prop string) error

func (*Location) RemRule

func (loc *Location) RemRule(ctx *Context, id string) (string, error)

func (*Location) ResolveService

func (loc *Location) ResolveService(ctx *Context, name string) (string, error)

func (*Location) RetryEventWork

func (loc *Location) RetryEventWork(ctx *Context, work *FindRules) *Condition

func (*Location) RuleEnabled

func (loc *Location) RuleEnabled(ctx *Context, id string) (bool, error)

func (*Location) RunJavascript

func (loc *Location) RunJavascript(ctx *Context, code string, libraries []string, bs *Bindings, props map[string]interface{}) (interface{}, error)

func (*Location) SearchFacts

func (loc *Location) SearchFacts(ctx *Context, pattern Map, includeInherited bool) (*SearchResults, error)

func (*Location) SearchLocations

func (loc *Location) SearchLocations(ctx *Context, locations []string, pattern map[string]interface{}) (*SearchResults, error)

func (*Location) SearchRemoteFacts

func (loc *Location) SearchRemoteFacts(ctx *Context, target string, pattern Map) (*SearchResults, error)

External fact service access

func (*Location) SearchRules

func (loc *Location) SearchRules(ctx *Context, event Map, includeInherited bool) (map[string]*Rule, error)

func (*Location) SetControl

func (loc *Location) SetControl(c *Control) *Control

func (*Location) SetParents

func (loc *Location) SetParents(ctx *Context, parents []string) (string, error)

SetParents sets a location's parents.

To remove a location's parents, just pass a zero array.

See comments re 'GetParents'.

func (*Location) SetProp

func (loc *Location) SetProp(ctx *Context, id string, prop string, val interface{}) error

func (*Location) SetReadOnly

func (loc *Location) SetReadOnly(ctx *Context, readOnly bool)

func (*Location) StateSize

func (loc *Location) StateSize(ctx *Context) (int, error)

func (*Location) Stats

func (loc *Location) Stats() *ServiceStats

func (*Location) Update

func (loc *Location) Update(ctx *Context, updating string) (string, string)

Update sets the in-memory timestamp of the last update.

If 'updating' is empty, then a value is generated using 'GenerateUpdateTimestamp()'. If 'updating' is "clear", then unset that state. Otherwise, the value of 'update' will be stored as the time the location was last updated.

Returns the previous value and the new value.

func (*Location) Updated

func (loc *Location) Updated(ctx *Context) string

Updated returns the in-memory timestamp of the last update.

func (*Location) WorkWalk

func (loc *Location) WorkWalk(ctx *Context, w *FindRules, steps int) *Condition

type LocationProvider

type LocationProvider interface {
	GetLocation(ctx *Context, name string) (*Location, error)
}

type LogHook

type LogHook func(level LogLevel, args ...interface{})

type LogLevel

type LogLevel uint64

LogLevel is really a bit field.

Confusingly still using the old name.

const (
	// SEVMASK is the list of severity bits.  Severities are
	// defined below.
	SEVMASK LogLevel = 0xff

	// ORIMASK is the list of origin bits.  An "origin" could be
	// user data, an external system, Core code itself, etc.
	ORIMASK LogLevel = 0xff00

	// COMPMASK is the list of component bits.  Components are
	// defined below.
	COMPMASK LogLevel = 0xffff0000
)
const (
	CRIT LogLevel = 1 << iota
	ERROR
	WARN
	POINT // Might not belong here.
	TIMER // Might not belong here.
	INFO
	DEBUG
	ABSURD

	// SYS origin means the core itself.
	SYS
	// USR origin means the log message was caused by user data.
	USR
	// APP origin means the log message was caused by an
	// "application", which typically means an external service.
	APP
	// METRIC is a "metric"
	METRIC

	// MISC is the catch-all component.
	MISC
	// MATCH is for pattern matching code.
	MATCH
	// STATE is for the in-memory state indexes.
	STATE
	// STORAGE is for the persistence implementations and associated layer.
	STORAGE
	// EVENT is for event processing.
	EVENT
	// SYSTEM is for sys/system.go: The outer-most package API layer.
	SYSTEM
	// EXTERN for external components.  Kinda sad.
	EXTERN
)

func ParseVerbosity

func ParseVerbosity(s string) (LogLevel, error)

ParseVerbosity parses and evals and log mask.

This function is a little crazy. It uses Javascript to parse and eval the given string. The various log constants are in the Javascript environment. For example, the string "ERROR|APP" would parse/eval 'ERROR|APP'. Since we're using Javascript, you can use Javascript numerics, too. Example: "0xffffffff".

The empty string is interpreted as 'EVERYTHING'. Use 'NOTHING' to get that.

type Logger

type Logger interface {
	Log(level LogLevel, args ...interface{})
	Metric(name string, args ...interface{})
}

Logger is a simple interface to a mostly generic logging functionality.

var BenchLogger Logger = NewSimpleLogger(ioutil.Discard)
var DefaultLogger Logger = NewSimpleLogger(os.Stdout)

type Map

type Map map[string]interface{}

Map is a generic event, pattern, or fact.

Kinda wants to be a transparent typedef.

func ExtractRule

func ExtractRule(ctx *Context, fact Map, required bool) (Map, error)

func MustMap

func MustMap(js string) Map

func ParseMap

func ParseMap(js string) (m Map, err error)

ParseMap tries to parse a Map from JSON.

func (Map) JSON

func (m Map) JSON() (string, error)

type Matcher

type Matcher interface {
	// Match takes a pattern and a fact built from map[string]interface{} and
	// []interface{} structures, along with an initial set of bindings (may be
	// empty), and returns a slice of sets of bindings representing the sets of
	// matches.
	Match(pattern, fact interface{}, bs Bindings) ([]Bindings, error)
}

Matcher defines an interface for pattern matching algorithms to be used by core.

type MemStorage

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

MemStorage is a in-memory-only implementation of Storage.

func NewMemStorage

func NewMemStorage(ctx *Context) (*MemStorage, error)

func (*MemStorage) Add

func (s *MemStorage) Add(ctx *Context, loc string, m *Pair) error

func (*MemStorage) Clear

func (s *MemStorage) Clear(ctx *Context, loc string) (int64, error)

func (*MemStorage) Close

func (s *MemStorage) Close(ctx *Context) error

func (*MemStorage) Delete

func (s *MemStorage) Delete(ctx *Context, loc string) error

func (*MemStorage) GetStats

func (s *MemStorage) GetStats(ctx *Context, loc string) (StorageStats, error)

GetStats isn't really implemented.

func (*MemStorage) Health

func (s *MemStorage) Health(ctx *Context) error

func (*MemStorage) Load

func (s *MemStorage) Load(ctx *Context, loc string) ([]Pair, error)

func (*MemStorage) Remove

func (s *MemStorage) Remove(ctx *Context, loc string, k []byte) (int64, error)

func (*MemStorage) SetState

func (s *MemStorage) SetState(ctx *Context, m map[string]map[string]string)

SetState is an unholy method that sets the raw data structure.

Just used for testing.

func (*MemStorage) State

func (s *MemStorage) State(ctx *Context) map[string]map[string]string

State is an unholy method that exposes the raw data structure.

Just used for testing.

type NoStorage

type NoStorage struct {
}

func NewNoStorage

func NewNoStorage(ctx *Context) (*NoStorage, error)

func (*NoStorage) Add

func (s *NoStorage) Add(ctx *Context, loc string, m *Pair) error

func (*NoStorage) Clear

func (s *NoStorage) Clear(ctx *Context, loc string) (int64, error)

func (*NoStorage) Close

func (s *NoStorage) Close(ctx *Context) error

func (*NoStorage) Delete

func (s *NoStorage) Delete(ctx *Context, loc string) error

func (*NoStorage) GetStats

func (s *NoStorage) GetStats(ctx *Context, loc string) (StorageStats, error)

func (*NoStorage) Health

func (s *NoStorage) Health(ctx *Context) error

func (*NoStorage) Load

func (s *NoStorage) Load(ctx *Context, loc string) ([]Pair, error)

func (*NoStorage) Remove

func (s *NoStorage) Remove(ctx *Context, loc string, k []byte) (int64, error)

type NoopLogger

type NoopLogger struct {
}

func (*NoopLogger) Log

func (l *NoopLogger) Log(level LogLevel, args ...interface{})

type NotFoundError

type NotFoundError struct {
	Msg string
}

func NewNotFoundError

func NewNotFoundError(s string, args ...interface{}) *NotFoundError

func (*NotFoundError) Error

func (e *NotFoundError) Error() string

func (*NotFoundError) IsFatal

func (e *NotFoundError) IsFatal() bool

func (*NotFoundError) String

func (e *NotFoundError) String() string

type NotQuery

type NotQuery struct {
	Negated Query
}

func (NotQuery) Exec

func (o NotQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

func (NotQuery) MarshalJSON

func (q NotQuery) MarshalJSON() ([]byte, error)

type OrQuery

type OrQuery struct {
	Disjuncts    []Query
	ShortCircuit bool
}

func (OrQuery) Exec

func (o OrQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

func (OrQuery) MarshalJSON

func (q OrQuery) MarshalJSON() ([]byte, error)

type OttoActionInterpreter

type OttoActionInterpreter struct {
}

OttoActionInterpreter is an example ActionInterpreter that does the same thing (currently) as the built-in "javascript" interpreter.

func (*OttoActionInterpreter) GetName

func (i *OttoActionInterpreter) GetName() string

GetName does what you'd thing.

For the ActionInterpreter interface.

func (*OttoActionInterpreter) GetThunk

func (i *OttoActionInterpreter) GetThunk(ctx *Context, loc *Location, bs Bindings, a Action) (func() (interface{}, error), error)

GetThunk returns the thunk that will interpret the action.

For the ActionInterpreter interface.

type OutboundBreaker

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

OutboundBreaker is a very simple circuit breaker.

An OutboundBreaker is used to control what this process does to other components or processes. It is not really designed to protect the local component or process.

An OutboundBreaker has a specified maximum rate, which is given by a count and a time.Duration. You ask a OutboundBreaker do Do() some function, which the OutboundBreaker will only do if the current rate is below the specified maximum.

An OutboundBreaker keeps a sliding state at a reasonable resolution.

Safe to use concurrently.

func NewOutboundBreaker

func NewOutboundBreaker(limit int64, interval time.Duration) (*OutboundBreaker, error)

NewOutboundBreaker makes a circuit breaker that will open if the Send rate exceeds the given rate (limit/interval).

func (*OutboundBreaker) Adjust

func (b *OutboundBreaker) Adjust(limit int64, interval time.Duration) error

Adjust allows a caller to change the circuit breaker's capacity.

func (*OutboundBreaker) Disable

func (b *OutboundBreaker) Disable(disabled bool)

func (*OutboundBreaker) Do

func (b *OutboundBreaker) Do(f func() error) (bool, error)

Do will execute the given thunk only if the circuit breaker is open.

Returns whether the function executed was attempted and, if it was, any error generated.

The function is executed after the OutboundBreaker's lock has been released.

func (*OutboundBreaker) Reset

func (b *OutboundBreaker) Reset()

Reset clears the breaker's state (but does not change its capacity).

func (*OutboundBreaker) Status

func (b *OutboundBreaker) Status() BreakerStatus

Rate reports the load (1.0 = 100%), current count, the breaker's interval, and whether the breaker is closed (good: true) or open (bad: false).

func (*OutboundBreaker) Summary

func (b *OutboundBreaker) Summary() string

Summary gives a one-line summary of the breaker's state.

func (*OutboundBreaker) Zap

func (b *OutboundBreaker) Zap() bool

Zap hits the circuit breaker and returns whether the breaker is then closed (good: true) or open (bad: false).

If the breaker is open when zapped, that zap will not add any load to the breaker.

type Pair

type Pair struct {
	K []byte
	V []byte
}

ToDo: Use this less

func (*Pair) String

func (d *Pair) String() string

type Parameters

type Parameters struct {

	// SlurpCacheSize is the maximum number of cached Slurp results
	SlurpCacheSize int

	// SlurpTimeout is that.
	SlurpTimeout time.Duration

	// SlurpCacheTTL is the TTL for SlurpCache entries.
	SlurpCacheTTL time.Duration

	// Timeout enables Javascript timeouts.
	JavascriptTimeouts bool

	// LogAccumulatorSize is the size of log accumulator buffers.
	LogAccumulatorSize int

	// HTTPClientCacheSize is the maximum number of HTTPClients to
	// cache.
	HTTPClientCacheSize int

	// HTTPClientCacheTTL is the TTL for a HTTPClientCache entry.
	HTTPClientCacheTTL time.Duration

	// IdLengthLimit is the maximum size for an id.
	IdLengthLimit int

	// IdInjectionTime determines the id injection mode.
	IdInjectionTime int

	// TimerHistorySize limits how many entries are stored for a given timer.
	TimerHistorySize int

	// TimerWarningLimit, when exceeded, generates a log warning.
	TimerWarningLimit time.Duration

	// MaxTimers limits the number of timers we track so bad data doesn't kill us.
	// This limit is not currently enforced!
	MaxTimers int

	// LogRecordValueLimit is the maximum value length in a LogRecord.
	// See MakeLogRecord() below
	LogRecordValueLimit int

	// LogCallerLine adds the line number of the callers to log records.
	LogCallerLine bool

	// ConcurrentWalks turns concurrent EventWorkWalking on or off.
	ConcurrentWalks bool

	// DefaultControl is the default Location.Control
	DefaultControl *Control

	// StringLengthTermLimit is the maximum length of a string that gets indexed.
	// If your string (in an FDS) is longer that this limit, it won't get
	// indexed.
	StringLengthTermLimit int

	// DefaultJavascriptTimeout does what you'd think.
	//
	// A Location's control can override this value (if
	// SystemParameters.Timeout is true).
	DefaultJavascriptTimeout time.Duration

	// MaxIdleConnsPerHost is that parameter for HTTP clients.
	MaxIdleConnsPerHost int

	// HTTPTimeout
	HTTPTimeout time.Duration

	// InsecureSkipVerify
	InsecureSkipVerify bool

	// DisableKeepAlives
	DisableKeepAlives bool

	// ResponseHeaderTimeout
	ResponseHeaderTimeout time.Duration

	// HTTPRetryInterval
	HTTPRetryInterval time.Duration

	// HTTPRetryOn
	HTTPRetryOn StringSet

	// CopyEvents will copy the binding for "?event" before giving
	// that data to condition javascript or a javascript action.
	CopyEvents bool
}

Parameters is a package of almost const parameters.

func DefaultParameters

func DefaultParameters() *Parameters

func SetParameters

func SetParameters(p *Parameters) *Parameters

func TightParameters

func TightParameters() *Parameters

func (*Parameters) Copy

func (ps *Parameters) Copy() *Parameters

Copy makes a shallow (except for DefaultControl) copy.

The DefaultControl is Copy()ed.

func (*Parameters) Log

func (ps *Parameters) Log(ctx *Context)

type PatternIndex

type PatternIndex struct {
	String map[string]*PatternIndex
	Var    *PatternIndex
	Map    *PatternIndex
	Ids    StringSet
}

PatternIndex is the state for our in-memory pattern store.

It indexes patterns. When given an event (or fact), this index should find candidates for matching patterns, which are typically the 'when's in rules.

Important: This code does NOT need to return only those patterns that match the input. Instead, this code needs to return all patterns that might match the input. Then other code (state_indexed.go) will process the results based on actual pattern matching.

The basic approach here: We have an ordering on all atomic values (strings, numbers), and we build a tree using that order. When given a fact, we start with lowest property. We look for that property in the tree. Say we find it at some node. Then we look at the fact's value at that property, and we look for that value in the node. Then we get the fact's next property, and we start looking at the same node. When we encounter a structured (non-atomic) value, we traverse a Map node instead of regular value.

That description is pretty confusing. See 'patstore_test.go' and add some 'i.Show()' calls to see how the index gets built.

func NewPatternIndex

func NewPatternIndex() *PatternIndex

NewPatternIndex does exactly what you think it does.

func (*PatternIndex) AddPatternMap

func (index *PatternIndex) AddPatternMap(ctx *Context, m map[string]interface{}, id string) error

AddPatternJSON adds the given pattern (as a map) to the index.

func (*PatternIndex) RemPatternMap

func (index *PatternIndex) RemPatternMap(ctx *Context, m map[string]interface{}, id string) error

RemPatternMap removes the given pattern from the index.

func (*PatternIndex) SearchPatternsMap

func (index *PatternIndex) SearchPatternsMap(ctx *Context, fact map[string]interface{}) (StringSet, error)

SearchPatternsMap searchs the index for patterns that match the given fact (or event).

func (*PatternIndex) Show

func (index *PatternIndex) Show()

Show prints the index to stdout in a readable way.

type PatternQuery

type PatternQuery struct {
	Pattern   map[string]interface{} `json:"pattern"`
	Locations []string               `json:"locations,omitempty"`
}

func (PatternQuery) Exec

func (p PatternQuery) Exec(ctx *Context, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

type PointHook

type PointHook func(ctx *Context, namespace string, metric string, val interface{}, unit string, more ...string)

type Problem

type Problem interface {
	IsFatal() bool
	Error() string
}

type Query

type Query interface {
	Exec(*Context, *Location, QueryContext, QueryResult) (*QueryResult, error)
}

func AndQueryFromMap

func AndQueryFromMap(ctx *Context, m map[string]interface{}) (Query, bool, error)

func CodeQueryFromMap

func CodeQueryFromMap(ctx *Context, m map[string]interface{}) (Query, bool, error)

func NotQueryFromMap

func NotQueryFromMap(ctx *Context, m map[string]interface{}) (Query, bool, error)

func OrQueryFromMap

func OrQueryFromMap(ctx *Context, m map[string]interface{}) (Query, bool, error)

func ParseQuery

func ParseQuery(ctx *Context, m map[string]interface{}) (q Query, err error)

func PatternQueryFromMap

func PatternQueryFromMap(ctx *Context, m map[string]interface{}) (Query, bool, error)

type QueryContext

type QueryContext struct {
	// Or maybe map[string]interface{} ...
	Locations []string
}

type QueryResult

type QueryResult struct {
	Bss     []Bindings
	Checked int
	Elapsed int64
}

func ExecQuery

func ExecQuery(ctx *Context, q Query, loc *Location, qc QueryContext, qr QueryResult) (*QueryResult, error)

func InitialQueryResult

func InitialQueryResult(ctx *Context) QueryResult

Make a QueryResult that contains one empty Bindings.

type RawFact

type RawFact struct {
	M  map[string]interface{}
	JS []byte
}

type RemHookFn

type RemHookFn func(ctx *Context, state State, id string) error

type Rule

type Rule struct {
	// The id for the rule.  The SHA1 has of the JSON is a good
	// 'id'.  That way the same rule added twice will not create
	// duplicate rules.
	Id string `json:"id,omitempty"`

	// Optional (but typical) pattern that will be matched against
	// incoming events.
	When *PatternQuery `json:"when,omitempty"`

	// Schedule is a crontab entry string or a duration starting with a "+".
	Schedule string `json:"schedule,omitempty"`

	// Optional query against facts (local or remote).
	Condition GenericQuery `json:"condition,omitempty"`

	// Actions: should have at least one.
	Actions []CleanAction `json:"actions,omitempty"`

	// Action just helps with unmarshalling.
	//
	// Will be stuck into Actions.
	Action *CleanAction `json:"action,omitempty"`

	Policies *RulePolicies `json:"policies,omitempty"`

	// Once specifies that the rule should be deleted after
	// exactly one evaluation.
	//
	// We didn't generalize to a count because we'd have to update
	// the rule state with each count decrement.
	Once bool `json:"once"`

	// Generic properties that are not currently used.
	Props map[string]interface{} `json:"props"`

	// Expires is an expiration time in UNIX seconds.
	//
	// 0 for no expiration.  This value is here to allow any
	// 'FindRules()' implementation drop expired rules.  Not all
	// implementations will need to consult this value.
	//
	// The type is float64 to deal with JSON serialization (and
	// since JSON only really has floats).
	Expires float64 `json:"expires"`
}

What a rule is.

Note: Order is no longer supported (for several reasons).

Note: 'Schedule' is not implemented (here).

func RuleFromJSON

func RuleFromJSON(ctx *Context, js []byte) (*Rule, error)

RuleToJSON generates a Rule from the given JSON representation.

func RuleFromMap

func RuleFromMap(ctx *Context, m map[string]interface{}) (*Rule, error)

RuleFromMap generates a Rule from a map.

type RuleDone

type RuleDone struct {
	Parent      *EvalRule  `json:"-"`
	Disposition *Condition `json:"disposition,omitempty"`
}

func (*RuleDone) Do

func (w *RuleDone) Do(ctx *Context, loc *Location)

type RulePolicies

type RulePolicies struct {
	// RetryFromCondition will mark a rule's 'EvalRuleCondition'
	// as incomplete if any of that rule's actions fail.
	//
	// So if you submit that work again, the entire rule will be
	// re-evaluated starting the the rule's condition.
	//
	// NOT CURRENTLY IMPLEMENTED.
	RetryFromCondition bool `json:"retryFromCondition,omitempty"`

	// VerifyEnabled will demand that 'EventWorkStep' (and,
	// therefore, 'EventWorkWalk') will verify each rule is
	// enabled (and exists) before re-evaluating any part of the
	// rule.
	//
	// NOT CURRENTLY IMPLEMENTED.
	VerifyEnabled bool `json:"verifyEnabled,omitempty"`

	// SerialActions, if true, will cause rule processing
	// components to be executed sequentially.  Otherwise a rule's
	// actions will be executed concurrently.
	SerialActions bool `json:"serialActions,omitempty"`
}

RulePolicies are experimental switches that influence 'ProcessEvent' and the 'EventWorkStep' that it returns.

type SearchResult

type SearchResult struct {
	Js        string
	Id        string
	Bindingss []Bindings
}

SearchResult packages up a found fact and the bindings that make it match the query.

type SearchResults

type SearchResults struct {
	Found   []SearchResult
	Checked int
	Elapsed int64
	Expired int
}

SearchResults packages up what a search found. When we search, we should remember how many candidate facts we had to test (Checked) in order to find actual matches. Part of the efficiency of extractTerms and the TermIndex is indicated by the number of false positives (Checked - len(Found)). This metric will be important.

func (*SearchResults) Merge

func (sr *SearchResults) Merge(more *SearchResults) *SearchResults

type ServiceStats

type ServiceStats struct {
	TotalCalls       uint64
	ErrorCount       uint64
	TotalTime        uint64
	NewLocations     uint64
	ListLocations    uint64
	AddRules         uint64
	UpdateRules      uint64
	RemRules         uint64
	GetRules         uint64
	AddFacts         uint64
	RemFacts         uint64
	GetFacts         uint64
	SearchRules      uint64
	SearchFacts      uint64
	ListRules        uint64
	ProcessEvents    uint64
	GetEventHistorys uint64
	ActionExecs      uint64
}

ServiceStats contains statistics that a System and each Location can track. Each stat should, I guess, be updated atomically:

atomic.AddUint64(&sys.stats.TotalCalls, uint64(1))

Though of course one wonders about when that atomic call is really needed.

Since we are using atomic ops instead of a struct-wide mutex (for speed), we will be unsure what the data really means. ToDo: Reconsider.

We also want to track stats on a per-app basis. Code that uses this package could do that.

func (*ServiceStats) Aggregate

func (stats *ServiceStats) Aggregate(src *ServiceStats)

Aggregate from given ServiceStats.

Updates the receiver.

func (*ServiceStats) Clone

func (stats *ServiceStats) Clone() *ServiceStats

Clone gives a clean copy of the given ServiceStats.

func (*ServiceStats) IncErrors

func (stats *ServiceStats) IncErrors(err error) error

IncErrors increments stats.ErrorCount if err isn't nil.

func (*ServiceStats) Log

func (stats *ServiceStats) Log(level LogLevel, ctx *Context, scope string)

Log emits a log line for the given stats. The 'scope' is included in the log record. Example scopes: 'system', location.Name.

func (*ServiceStats) LogLoop

func (stats *ServiceStats) LogLoop(level LogLevel, ctx *Context, scope string, interval time.Duration, iterations int)

LogLoop starts a loop that calls stats.Log at the given interval.

If iterations is negative, the loop is endless. Otherwise the loop terminates after the specified number of iteratins.

func (*ServiceStats) Reset

func (stats *ServiceStats) Reset()

Reset resets all fields to zeros.

Stores are done with atomics, so ...

func (*ServiceStats) Subtract

func (stats *ServiceStats) Subtract(y *ServiceStats) *ServiceStats

Subtract subtracts the given stats from the receiver.

The receiver is cloned first, and the updated clone is returned.

type SheensMatcher

type SheensMatcher struct {
	*match.Matcher
}

SheensMatcher wraps the matcher provided by the github.com/Comcast/sheens/match for use by rulio.

func (SheensMatcher) Match

func (m SheensMatcher) Match(pattern, fact interface{}, bs Bindings) ([]Bindings, error)

Match implements the Matcher interface.

type SimpleBreaker

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

SimpleBreaker is a breaker based on some function that returns a float64.

func GoroutineBreaker

func GoroutineBreaker(limit int) *SimpleBreaker

GoroutineBreaker makes a SimpleBreaker based on goroutine count.

func NewSimpleBreaker

func NewSimpleBreaker(probe func() (float64, error), limit float64) *SimpleBreaker

func (*SimpleBreaker) Disable

func (c *SimpleBreaker) Disable(disabled bool)

func (*SimpleBreaker) Do

func (c *SimpleBreaker) Do(f func() error) (bool, error)

func (*SimpleBreaker) Status

func (c *SimpleBreaker) Status() BreakerStatus

type SimpleLocationProvider

type SimpleLocationProvider struct {
	Registry map[string]*Location
}

func NewSimpleLocationProvider

func NewSimpleLocationProvider(locs map[string]*Location) *SimpleLocationProvider

func (*SimpleLocationProvider) GetLocation

func (p *SimpleLocationProvider) GetLocation(ctx *Context, name string) (*Location, error)

type SimpleLogger

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

func NewSimpleLogger

func NewSimpleLogger(w io.Writer) *SimpleLogger

func (*SimpleLogger) Log

func (sl *SimpleLogger) Log(level LogLevel, args ...interface{})

Log implements part of the Logger interface.

func (*SimpleLogger) Metric

func (sl *SimpleLogger) Metric(name string, args ...interface{})

Metric implements part of the Logger interface.

type State

type State interface {
	Count(ctx *Context) int
	AddHook(hook AddHookFn)
	RemHook(hook RemHookFn)
	Load(ctx *Context) error
	Add(ctx *Context, id string, x Map) (string, error)
	Rem(ctx *Context, id string) (bool, error)
	Delete(ctx *Context) error
	Get(ctx *Context, id string) (Map, error)

	Search(ctx *Context, pattern Map) (*SearchResults, error)
	FindRules(ctx *Context, event Map) (map[string]Map, error)
	FindCachedRules(ctx *Context, event Map) (map[string]*Rule, error)
	Clear(ctx *Context) error
	// contains filtered or unexported methods
}

type Storage

type Storage interface {
	Load(ctx *Context, loc string) ([]Pair, error)

	Add(ctx *Context, loc string, data *Pair) error

	Remove(ctx *Context, loc string, k []byte) (int64, error)

	Clear(ctx *Context, loc string) (int64, error)

	Delete(ctx *Context, loc string) error

	GetStats(ctx *Context, loc string) (StorageStats, error)

	Close(ctx *Context) error

	Health(ctx *Context) error
}

type StorageStats

type StorageStats struct {
	NumRecords       int
	DateOfLastRecord string
}

type StringSet

type StringSet map[string]struct{}

StringSet represents a set of strings.

A StringSet is not synchronized.

func EmptyStringSet

func EmptyStringSet() StringSet

EmptyStringSet makes one of those.

func NewStringSet

func NewStringSet(xs []string) StringSet

NewStringSet does what you'd expect.

func (StringSet) Add

func (s StringSet) Add(x string) StringSet

Add adds the given string to the set.

func (StringSet) AddAll

func (s StringSet) AddAll(more StringSet) StringSet

AddAll adds all elements of the given set to the set.

func (StringSet) AddStrings

func (s StringSet) AddStrings(xs ...string) StringSet

func (StringSet) Array

func (xs StringSet) Array() []string

Array returns a pointer to an array of the set's elements.

func (StringSet) Contains

func (s StringSet) Contains(x string) bool

Contains reports whether the given string is in the set

func (StringSet) Difference

func (xs StringSet) Difference(ys StringSet) (StringSet, StringSet)

Difference returns a new set containing the elements in receiver that are not in the given set.

No sets are harmed in this operation.

func (StringSet) Intersect

func (s StringSet) Intersect(t StringSet)

Insert removes elements not in the given set.

The receiver is modified.

func (StringSet) MarshalJSON

func (s StringSet) MarshalJSON() ([]byte, error)

func (StringSet) Rem

func (s StringSet) Rem(x string) StringSet

Rem does what you'd think.

func (StringSet) UnmarshalJSON

func (s StringSet) UnmarshalJSON(data []byte) error

type SyntaxError

type SyntaxError struct {
	Msg string
}

func NewSyntaxError

func NewSyntaxError(s string, args ...interface{}) *SyntaxError

func (*SyntaxError) Error

func (e *SyntaxError) Error() string

func (*SyntaxError) IsFatal

func (e *SyntaxError) IsFatal() bool

func (*SyntaxError) String

func (e *SyntaxError) String() string

type TermIndex

type TermIndex struct {
	Index map[string]StringSet
}

The main structure: A map from terms to sets of IDs. A fact is indexed by its terms. This implementation uses hash tables, so we cannot do prefix searches. (We could if we used some sort of ordered set such as a B*tree.) Therefore, our terms must no have structure (like 'a.b.c' from a fact '{a:{b:c}}'). We'll use strings as our fact IDs.

func NewTermIndex

func NewTermIndex() *TermIndex

func (*TermIndex) Add

func (ti *TermIndex) Add(ctx *Context, term string, id string)

Index the given fact ID at the given term.

func (*TermIndex) FastMetrics

func (ti *TermIndex) FastMetrics(ctx *Context) *TermIndexMetrics

Populate TermIndexMetrics with only metrics that are quick to compute. Also see 'SlowTermIndexMetrics'.

func (*TermIndex) Rem

func (ti *TermIndex) Rem(ctx *Context, term string, id string)

Remove the given ID at the given term.

func (*TermIndex) RemID

func (ti *TermIndex) RemID(ctx *Context, id string)

Remove all entries for the given fact ID. Must check every term, so this operation is slow. Use 'RemIdTerms' if you know a fact's terms.

func (*TermIndex) RemIdTerms

func (ti *TermIndex) RemIdTerms(ctx *Context, terms []string, id string)

Remove all entries for the given ID at the given terms.

func (*TermIndex) Search

func (ti *TermIndex) Search(ctx *Context, terms []string) ([]string, error)

Search the index. The algorithm is current pretty naive but reasonably efficient. We start with a term that has the lowest cardinality. The set of IDs for that term becomes the set of candidate IDs. For each remaining given term, eliminate a candidate if it does not appear in every set of remaining terms. func Search(ctx *Context, ti *TermIndex, terms []string) ([]string, error) {

func (*TermIndex) Show

func (ti *TermIndex) Show()

Print a JSON representation of the index.

func (*TermIndex) SlowMetrics

func (ti *TermIndex) SlowMetrics(ctx *Context) *TermIndexMetrics

Fully populate TermIndexMetrics. This function traverses all of the sets in the index, so this function can take a while to execute. Also see 'FastMetrics'.

func (*TermIndex) TermCard

func (ti *TermIndex) TermCard(ctx *Context, term string) int

How big is the set of IDs for the given term?

type TermIndexMetrics

type TermIndexMetrics struct {
	TermCount  int
	EntryCount int
	IdCount    int // Slow
	IdDups     int // Slow
}

Basic statistics about a TermIndex. 'entryCount' is the sum of the sizes of the IDs sets for each term. 'idCount' is the number of IDs put into the index. 'idDups' is the number of repeated IDs.

type ThingSlice

type ThingSlice []interface{}

ThingSlice is a slice of interfaces.

This type exists because we need to sort homogeneous arrays with various element types, and we don't want to copy data. Maybe there is a better way. Callers should check IsHomogeneous() before calling sort.Sort().

func AsThingSlice

func AsThingSlice(xs []interface{}) (ThingSlice, error)

func (ThingSlice) Len

func (a ThingSlice) Len() int

func (ThingSlice) Less

func (a ThingSlice) Less(i, j int) bool

Less provides a somewhat generic comparison.

Callers should check IsSortable() before invoking this method. If the given ThingSlice is heterogeneous, this method will panic.

Also see 'IsAtomic()'.

func (ThingSlice) Swap

func (a ThingSlice) Swap(i, j int)

type Throttle

type Throttle struct {
	sync.Mutex

	Breaker
	// contains filtered or unexported fields
}

Throttle is kind of a dumb function execution throttler based on a OutboundBreaker.

func NewThrottle

func NewThrottle(attempts int, pendingLimit int, pause time.Duration, b Breaker) (*Throttle, error)

NewThrottle creates a new Throttle based on an embedded Breaker.

'pause' specifies how long to wait between trying the breaker.

'attempts' specifies how many times to poll the breaker.

'pendingLimit' is the maximum number of pending throttling submits.

'pending' is the current number of pending throttling submits.

You Submit() work to a Throttle, and the Throttle will do that work as soon as (more or less) the current rate is below the Throttle's Breaker's maximum rate.

func (*Throttle) Disable

func (t *Throttle) Disable(disabled bool)

func (*Throttle) Modify

func (t *Throttle) Modify(pause time.Duration, attempts int)

Modify allows you to change the Throttle's specifications.

You can also change the embedded Breaker using 'Adjust()'.

func (*Throttle) Pending

func (t *Throttle) Pending() (int, float64)

Pending reports how many throttle submissions are pending.

Also returns the load (relative to the maximum pending submissions).

func (*Throttle) Submit

func (t *Throttle) Submit(f func() error) error

Submit sends a thunk to the throttle.

The throttle will execute the thunk only if the embedded Breaker says it can. If the function is executed, it's error (if any) is returned. This function can also return ThrottleExhausted or ThrottleOverflow.

The given function should not panic even if the caller tries to recover.

type Timer

type Timer struct {
	Ctx     *Context
	Id      int64
	S       string
	Then    int64
	Elapsed int64
	Paused  bool
}

func NewTimer

func NewTimer(ctx *Context, s string) *Timer

NewTimer makes a new timer with the given name.

Ctx is optional. If provided and if its system's configuration 'Timing' parameter is false, the a no-op timer will be returned.

func (*Timer) Elapse

func (t *Timer) Elapse() int64

Elapsed computes the elapsed time in nanoseconds.

This method does not change the timer state.

func (*Timer) Pause

func (t *Timer) Pause()

Pause stops the clock.

func (*Timer) Reset

func (t *Timer) Reset()

Reset zeros the current elapsed time and resets the current time.

func (*Timer) Resume

func (t *Timer) Resume()

Resume restarts a paused timer.

func (*Timer) Stop

func (t *Timer) Stop() int64

Stop computes the elapsed time (in nanosecs) and stores it in the history.

func (*Timer) StopTag

func (t *Timer) StopTag(tag string) int64

StopTag computes the elapsed time (in nanosecs) and stores it in the history.

This method also logs (level -1) the elapsed time with the given tag.

type TimerHistory

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

TimerHistory stores a history for each timer. This history is a circular buffer.

func (*TimerHistory) Copy

func (history *TimerHistory) Copy() *TimerHistory

We'll need to make an atomic copy of a history for API GetTimerHistory.

type TimerHistoryEntry

type TimerHistoryEntry struct {
	// Monotonically increase sequence number.
	Seq int

	// 2014-07-03T16:12:19.902Z.  Truncated to millis because so
	// many external systems don't automatically deal with
	// nanoseconds.
	Timestamp string

	// Nanoseconds.
	Elapsed int64
}

TimerHistoryEntry stores a bit of timer state at a point in time.

func GetTimerHistory

func GetTimerHistory(name string, after int, limit int) []TimerHistoryEntry

GetTimerHistory gets a history for timers with the given name. 'after' is sequence number corresponding to 'Seq' in entries you've previously gotten. Use -1 to start. 'limit' does what you'd think.

type Tracer

type Tracer interface {
	// StartSpan is given a new subcontext and the name of the operation that
	// the context is for.  The function is expected to modify the context with
	// any span information that is needed to pass on to child spans as well as
	// to stop the span.
	StartSpan(ctx *Context, opName string)

	// StopSpan is given a context previously given to StartSpan in order to
	// finalize the trace for the given span.
	StopSpan(ctx *Context)
}

Tracer can be used to perform application tracing.

Jump to

Keyboard shortcuts

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