graphvent

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2023 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const NODE_DB_HEADER_LEN = 12

Total length of the node database header, has magic to verify and type_hash to map to load function

View Source
const NODE_DB_MAGIC = 0x2491df14

Magic first four bytes of serialized DB content, stored big endian

View Source
const THREAD_SIGNAL_BUFFER_SIZE = 128

Variables

View Source
var BaseThreadActions = ThreadActions{
	"wait":    ThreadWait,
	"start":   ThreadDefaultStart,
	"restore": ThreadDefaultRestore,
}
View Source
var BaseThreadHandlers = ThreadHandlers{
	"abort":  ThreadAbort,
	"cancel": ThreadCancel,
}
View Source
var ThreadDefaultRestore = func(ctx *Context, thread Thread) (string, error) {
	ctx.Log.Logf("thread", "THREAD_DEFAULT_RESTORE: %s", thread.ID())
	return "wait", nil
}
View Source
var ThreadDefaultStart = func(ctx *Context, thread Thread) (string, error) {
	ctx.Log.Logf("thread", "THREAD_DEFAULT_START: %s", thread.ID())
	err := ThreadStart(ctx, thread)
	if err != nil {
		return "", err
	}
	return "wait", nil
}
View Source
var ThreadStart = func(ctx *Context, thread Thread) error {
	err := UpdateStates(ctx, []Node{thread}, func(nodes NodeMap) error {
		owner_id := NodeID("")
		if thread.Owner() != nil {
			owner_id = thread.Owner().ID()
		}
		if owner_id != thread.ID() {
			err := LockLockables(ctx, []Lockable{thread}, thread, nodes)
			if err != nil {
				return err
			}
		}
		return thread.SetState("started")
	})

	if err != nil {
		return err
	}

	return nil
}
View Source
var ThreadWait = func(ctx *Context, thread Thread) (string, error) {
	ctx.Log.Logf("thread", "THREAD_WAIT: %s TIMEOUT: %+v", thread.ID(), thread.Timeout())
	for {
		select {
		case signal := <-thread.SignalChannel():
			if signal.Source() == thread.ID() {
				ctx.Log.Logf("thread", "THREAD_SIGNAL_INTERNAL")
			} else {
				ctx.Log.Logf("thread", "THREAD_SIGNAL: %s %+v", thread.ID(), signal)
			}
			signal_fn, exists := thread.Handler(signal.Type())
			if exists == true {
				ctx.Log.Logf("thread", "THREAD_HANDLER: %s - %s", thread.ID(), signal.Type())
				return signal_fn(ctx, thread, signal)
			} else {
				ctx.Log.Logf("thread", "THREAD_NOHANDLER: %s - %s", thread.ID(), signal.Type())
			}
		case <-thread.Timeout():
			timeout_action := ""
			err := UpdateStates(ctx, []Node{thread}, func(nodes NodeMap) error {
				timeout_action = thread.TimeoutAction()
				thread.ClearTimeout()
				return nil
			})
			if err != nil {
				ctx.Log.Logf("thread", "THREAD_TIMEOUT_ERR: %s - %e", thread.ID(), err)
			}
			ctx.Log.Logf("thread", "THREAD_TIMEOUT %s - NEXT_STATE: %s", thread.ID(), timeout_action)
			return timeout_action, nil
		}
	}
}

Functions

func ChildGo

func ChildGo(ctx *Context, thread Thread, child Thread, first_action string)

func GQLHandler

func GQLHandler(ctx *Context, server *GQLThread) func(http.ResponseWriter, *http.Request)

func GQLInterfaceLockable

func GQLInterfaceLockable() *graphql.Interface

func GQLInterfaceNode

func GQLInterfaceNode() *graphql.Interface

func GQLInterfaceThread

func GQLInterfaceThread() *graphql.Interface

func GQLListLockable

func GQLListLockable() *graphql.List

func GQLListThread

func GQLListThread() *graphql.List

func GQLLockableDependencies

func GQLLockableDependencies(p graphql.ResolveParams) (interface{}, error)

func GQLLockableName

func GQLLockableName(p graphql.ResolveParams) (interface{}, error)

func GQLLockableOwner

func GQLLockableOwner(p graphql.ResolveParams) (interface{}, error)

func GQLLockableRequirements

func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error)

func GQLMutationSendUpdate

func GQLMutationSendUpdate() *graphql.Field

func GQLNodeID

func GQLNodeID(p graphql.ResolveParams) (interface{}, error)

func GQLQuerySelf

func GQLQuerySelf() *graphql.Field

func GQLSignalDirection

func GQLSignalDirection(p graphql.ResolveParams) (interface{}, error)

func GQLSignalFn

func GQLSignalFn(p graphql.ResolveParams, fn func(GraphSignal, graphql.ResolveParams) (interface{}, error)) (interface{}, error)

func GQLSignalSource

func GQLSignalSource(p graphql.ResolveParams) (interface{}, error)

func GQLSignalString

func GQLSignalString(p graphql.ResolveParams) (interface{}, error)

func GQLSignalType

func GQLSignalType(p graphql.ResolveParams) (interface{}, error)

func GQLSubscribeFn

func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*Context, *GQLThread, GraphSignal, graphql.ResolveParams) (interface{}, error)) (interface{}, error)

func GQLSubscribeSelf

func GQLSubscribeSelf(p graphql.ResolveParams) (interface{}, error)

func GQLSubscribeSignal

func GQLSubscribeSignal(p graphql.ResolveParams) (interface{}, error)

func GQLSubscriptionSelf

func GQLSubscriptionSelf() *graphql.Field

func GQLSubscriptionUpdate

func GQLSubscriptionUpdate() *graphql.Field

func GQLThreadChildren

func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error)

func GQLThreadListen

func GQLThreadListen(p graphql.ResolveParams) (interface{}, error)

func GQLThreadParent

func GQLThreadParent(p graphql.ResolveParams) (interface{}, error)

func GQLTypeGQLThread

func GQLTypeGQLThread() *graphql.Object

func GQLTypeGraphNode

func GQLTypeGraphNode() *graphql.Object

func GQLTypeSignal

func GQLTypeSignal() *graphql.Object

func GQLTypeSignalInput

func GQLTypeSignalInput() *graphql.InputObject

func GQLTypeSimpleLockable

func GQLTypeSimpleLockable() *graphql.Object

func GQLTypeSimpleThread

func GQLTypeSimpleThread() *graphql.Object

func GQLWSDo

func GQLWSDo(ctx *Context, p graphql.Params) chan *graphql.Result

func GQLWSHandler

func GQLWSHandler(ctx *Context, server *GQLThread) func(http.ResponseWriter, *http.Request)

func GraphiQLHandler

func GraphiQLHandler() func(http.ResponseWriter, *http.Request)

func LinkLockables

func LinkLockables(ctx *Context, lockable Lockable, requirements []Lockable, nodes NodeMap) error

Link requirements as requirements to lockable Requires lockable and requirements to be locked for write, nodes passed because requirement check recursively locks

func LinkThreads

func LinkThreads(ctx *Context, thread Thread, child Thread, info ThreadInfo, nodes NodeMap) error

Requires thread and childs thread to be locked for write

func LockLockables

func LockLockables(ctx *Context, to_lock []Lockable, new_owner Lockable, nodes NodeMap) error

Lock nodes in the to_lock slice with new_owner, does not modify any states if returning an error Requires that all the nodes in to_lock and new_owner are locked for write

func RestoreSimpleLockable

func RestoreSimpleLockable(ctx *Context, lockable Lockable, j SimpleLockableJSON, nodes NodeMap) error

Helper function to load links when loading a struct that embeds SimpleLockable

func RestoreSimpleThread

func RestoreSimpleThread(ctx *Context, thread Thread, j SimpleThreadJSON, nodes NodeMap) error

func ThreadAbort

func ThreadAbort(ctx *Context, thread Thread, signal GraphSignal) (string, error)

Default thread abort is to return a ThreadAbortedError

func ThreadCancel

func ThreadCancel(ctx *Context, thread Thread, signal GraphSignal) (string, error)

Default thread cancel is to finish the thread

func ThreadLoop

func ThreadLoop(ctx *Context, thread Thread, first_action string) error

Main Loop for Threads

func UnlinkLockables

func UnlinkLockables(ctx *Context, lockable Lockable, requirement Lockable) error

Removes requirement as a requirement from lockable Requires lockable and requirement be locked for write

func UnlinkThreads

func UnlinkThreads(ctx *Context, thread Thread, child Thread) error

Requires thread and childs thread to be locked for write

func UnlockLockables

func UnlockLockables(ctx *Context, to_unlock []Lockable, old_owner Lockable, nodes NodeMap) error

Unlock nodes in the to_unlock slice with old_owner, does not modify any states if returning an error Requires that all the nodes in to_unlock and old_owner are locked for write

func UpdateChannel

func UpdateChannel(node Node, buffer int, id NodeID) chan GraphSignal

Create a new channel with a buffer the size of buffer, and register it to node with the id

func UpdateMoreStates

func UpdateMoreStates(ctx *Context, nodes []Node, locked_nodes NodeMap, nodes_fn NodesFn) error

Add nodes to an existing write context and call nodes_fn with nodes locked for read

func UpdateStates

func UpdateStates(ctx *Context, nodes []Node, nodes_fn NodesFn) error

Initiate a write context for nodes and call nodes_fn with nodes locked for read

func UseMoreStates

func UseMoreStates(ctx *Context, new_nodes []Node, nodes NodeMap, nodes_fn NodesFn) error

Add nodes to an existing read context and call nodes_fn with new_nodes locked for read

func UseStates

func UseStates(ctx *Context, init_nodes []Node, nodes_fn NodesFn) error

Initiate a read context for nodes and call nodes_fn with init_nodes locked for read

func WriteNodes

func WriteNodes(ctx *Context, nodes NodeMap) error

Write multiple nodes to the database in a single transaction

Types

type BaseSignal

type BaseSignal struct {
	FDirection SignalDirection `json:"direction"`
	FSource    NodeID          `json:"source"`
	FType      string          `json:"type"`
}

BaseSignal is the most basic type of signal, it has no additional data

func AbortSignal

func AbortSignal(source Node) BaseSignal

func CancelSignal

func CancelSignal(source Node) BaseSignal

func NewBaseSignal

func NewBaseSignal(source Node, _type string, direction SignalDirection) BaseSignal

func NewDirectSignal

func NewDirectSignal(source Node, _type string) BaseSignal

func NewDownSignal

func NewDownSignal(source Node, _type string) BaseSignal

func NewSignal

func NewSignal(source Node, _type string) BaseSignal

func (BaseSignal) Direction

func (signal BaseSignal) Direction() SignalDirection

func (BaseSignal) Source

func (signal BaseSignal) Source() NodeID

func (BaseSignal) String

func (state BaseSignal) String() string

func (BaseSignal) Type

func (signal BaseSignal) Type() string

type ConsoleLogger

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

A ConsoleLogger logs to stdout

func NewConsoleLogger

func NewConsoleLogger(components []string) *ConsoleLogger

func (*ConsoleLogger) Logf

func (logger *ConsoleLogger) Logf(component string, format string, items ...interface{})

func (*ConsoleLogger) Logj

func (logger *ConsoleLogger) Logj(component string, s interface{}, format string, items ...interface{})

func (*ConsoleLogger) Logm

func (logger *ConsoleLogger) Logm(component string, fields map[string]interface{}, format string, items ...interface{})

func (*ConsoleLogger) SetComponents

func (logger *ConsoleLogger) SetComponents(components []string) error

type Context

type Context struct {
	// DB is the database connection used to load and write nodes
	DB *badger.DB
	// Log is an interface used to record events happening
	Log Logger
	// A mapping between type hashes and their corresponding node definitions
	Types map[uint64]NodeDef
	// GQL substructure
	GQL GQLContext
}

A Context is all the data needed to run a graphvent

func NewContext

func NewContext(db *badger.DB, log Logger) *Context

Create a new Context with all the library content added

func (*Context) AddGQLType

func (ctx *Context) AddGQLType(gql_type graphql.Type)

Add a non-node type to the gql context

func (*Context) RebuildSchema

func (ctx *Context) RebuildSchema() error

Recreate the GQL schema after making changes

func (*Context) RegisterNodeType

func (ctx *Context) RegisterNodeType(def NodeDef) error

Add a node to a context, returns an error if the def is invalid or already exists in the context

type DBHeader

type DBHeader struct {
	Magic    uint32
	TypeHash uint64
}

A DBHeader is parsed from the first NODE_DB_HEADER_LEN bytes of a serialized DB node

func NewDBHeader

func NewDBHeader(node_type NodeType) DBHeader

func (DBHeader) Serialize

func (header DBHeader) Serialize() []byte

type GQLContext

type GQLContext struct {
	// Generated GQL schema
	Schema graphql.Schema

	// Interface types to compare against
	NodeType     reflect.Type
	LockableType reflect.Type
	ThreadType   reflect.Type

	// List of GQL types
	TypeList []graphql.Type

	// Interface type maps to map go types of specific interfaces to gql types
	ValidNodes     ObjTypeMap
	ValidLockables ObjTypeMap
	ValidThreads   ObjTypeMap

	Query        *graphql.Object
	Mutation     *graphql.Object
	Subscription *graphql.Object
}

GQL Specific Context information

func NewGQLContext

func NewGQLContext() GQLContext

Create a new GQL context without any content

type GQLThread

type GQLThread struct {
	SimpleThread

	Listen string
	// contains filtered or unexported fields
}

func NewGQLThread

func NewGQLThread(id NodeID, name string, state_name string, listen string) GQLThread

func (*GQLThread) DeserializeInfo

func (thread *GQLThread) DeserializeInfo(ctx *Context, data []byte) (ThreadInfo, error)

func (*GQLThread) Serialize

func (thread *GQLThread) Serialize() ([]byte, error)

func (*GQLThread) Type

func (thread *GQLThread) Type() NodeType

type GQLThreadInfo

type GQLThreadInfo struct {
	Start         bool   `json:"start"`
	StartAction   string `json:"start_action"`
	RestoreAction string `json:"restore_action"`
}

func NewGQLThreadInfo

func NewGQLThreadInfo(start bool, start_action string, restore_action string) GQLThreadInfo

type GQLThreadJSON

type GQLThreadJSON struct {
	SimpleThreadJSON
	Listen string `json:"listen"`
}

func NewGQLThreadJSON

func NewGQLThreadJSON(thread *GQLThread) GQLThreadJSON

type GQLWSMsg

type GQLWSMsg struct {
	ID      string       `json:"id,omitempty"`
	Type    string       `json:"type"`
	Payload GQLWSPayload `json:"payload,omitempty"`
}

type GQLWSPayload

type GQLWSPayload struct {
	OperationName string                 `json:"operationName,omitempty"`
	Query         string                 `json:"query,omitempty"`
	Variables     map[string]interface{} `json:"variables,omitempty"`
	Extensions    map[string]interface{} `json:"extensions,omitempty"`
	Data          string                 `json:"data,omitempty"`
}

type GraphNode

type GraphNode struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

A GraphNode is an implementation of a Node that can be embedded into more complex structures

func NewGraphNode

func NewGraphNode(id NodeID) GraphNode

func (*GraphNode) ID

func (node *GraphNode) ID() NodeID

func (*GraphNode) RegisterChannel

func (node *GraphNode) RegisterChannel(id NodeID, listener chan GraphSignal)

func (*GraphNode) Serialize

func (node *GraphNode) Serialize() ([]byte, error)

GraphNode doesn't serialize any additional information by default

func (*GraphNode) Signal

func (node *GraphNode) Signal(ctx *Context, signal GraphSignal, nodes NodeMap) error

Propagate the signal to registered listeners, if a listener isn't ready to receive the update send it a notification that it was closed and then close it

func (*GraphNode) Type

func (node *GraphNode) Type() NodeType

func (*GraphNode) UnregisterChannel

func (node *GraphNode) UnregisterChannel(id NodeID)

type GraphSignal

type GraphSignal interface {
	// How to propogate the signal
	Direction() SignalDirection
	Source() NodeID
	Type() string
	String() string
}

GraphSignals are passed around the event tree/resource DAG and cast by Type()

type Lockable

type Lockable interface {
	// All Lockables are nodes
	Node
	//// State Modification Function
	// Record that lockable was returned to it's owner and is no longer held by this Node
	// Returns the previous owner of the lockable
	RecordUnlock(lockable Lockable) Lockable
	// Record that lockable was locked by this node, and that it should be returned to last_owner
	RecordLock(lockable Lockable, last_owner Lockable)
	// Link a requirement to this Node
	AddRequirement(requirement Lockable)
	// Remove a requirement linked to this Node
	RemoveRequirement(requirement Lockable)
	// Link a dependency to this Node
	AddDependency(dependency Lockable)
	// Remove a dependency linked to this Node
	RemoveDependency(dependency Lockable)
	//
	SetOwner(new_owner Lockable)

	//// State Reading Functions
	Name() string
	// Called when new_owner wants to take lockable's lock but it's owned by this node
	// A true return value means that the lock can be passed
	AllowedToTakeLock(new_owner Lockable, lockable Lockable) bool
	// Get all the linked requirements to this node
	Requirements() []Lockable
	// Get all the linked dependencies to this node
	Dependencies() []Lockable
	// Get the node's Owner
	Owner() Lockable
	// Called during the lock process after locking the state and before updating the Node's state
	// a non-nil return value will abort the lock attempt
	CanLock(new_owner Lockable) error
	// Called during the unlock process after locking the state and before updating the Node's state
	// a non-nil return value will abort the unlock attempt
	CanUnlock(old_owner Lockable) error
}

A Lockable represents a Node that can be locked and hold other Nodes locks

type Logger

type Logger interface {
	SetComponents(components []string) error
	// Log a formatted string
	Logf(component string, format string, items ...interface{})
	// Log a map of attributes and a format string
	Logm(component string, fields map[string]interface{}, format string, items ...interface{})
	// Log a structure to a file by marshalling and unmarshalling the json
	Logj(component string, s interface{}, format string, items ...interface{})
}

A Logger is passed around to record events happening to components enabled by SetComponents

type Node

type Node interface {
	sync.Locker
	RLock()
	RUnlock()
	// Serialize the Node for the database
	Serialize() ([]byte, error)
	ID() NodeID
	Type() NodeType
	// Send a GraphSignal to the node, requires that the node is locked for read so that it can propagate
	Signal(ctx *Context, signal GraphSignal, nodes NodeMap) error
	// Register a channel to receive updates sent to the node
	RegisterChannel(id NodeID, listener chan GraphSignal)
	// Unregister a channel from receiving updates sent to the node
	UnregisterChannel(id NodeID)
}

A Node represents data that can be read by multiple goroutines and written to by one, with a unique ID attached, and a method to process updates(including propagating them to connected nodes) RegisterChannel and UnregisterChannel are used to connect arbitrary listeners to the node

func LoadGQLThread

func LoadGQLThread(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)

func LoadGraphNode

func LoadGraphNode(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)

func LoadNode

func LoadNode(ctx *Context, id NodeID) (Node, error)

Load a Node from the database by ID

func LoadNodeRecurse

func LoadNodeRecurse(ctx *Context, id NodeID, nodes NodeMap) (Node, error)

Recursively load a node from the database. It's expected that node_type.Load adds the newly loaded node to nodes before calling LoadNodeRecurse again.

func LoadSimpleLockable

func LoadSimpleLockable(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)

Load function for SimpleLockable

func LoadSimpleThread

func LoadSimpleThread(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error)

func NodeList

func NodeList[K Node](list []K) []Node

Convert any slice of types that implement Node to a []Node

type NodeDef

type NodeDef struct {
	Load    NodeLoadFunc
	Type    NodeType
	GQLType *graphql.Object
	Reflect reflect.Type
}

A NodeDef is a description of a node that can be added to a Context

func NewNodeDef

func NewNodeDef(example Node, load_func NodeLoadFunc, gql_type *graphql.Object) NodeDef

Create a new Node def, extracting the Type and Reflect from example

type NodeID

type NodeID string

IDs are how nodes are uniquely identified, and can be serialized for the database

func RandID

func RandID() NodeID

Generate a random NodeID

func (NodeID) Serialize

func (id NodeID) Serialize() []byte

type NodeLoadFunc

type NodeLoadFunc func(*Context, NodeID, []byte, NodeMap) (Node, error)

NodeLoadFunc is the footprint of the function used to create a new node in memory from persisted bytes

type NodeMap

type NodeMap map[NodeID]Node

type NodeType

type NodeType string

Types are how nodes are associated with structs at runtime(and from the DB)

func (NodeType) Hash

func (node_type NodeType) Hash() uint64

type NodesFn

type NodesFn func(nodes NodeMap) error

type ObjTypeMap

type ObjTypeMap map[reflect.Type]*graphql.Object

Map of go types to graphql types

type SignalDirection

type SignalDirection int
const (
	Up SignalDirection = iota
	Down
	Direct
)

type SimpleLockable

type SimpleLockable struct {
	GraphNode
	// contains filtered or unexported fields
}

SimpleLockable is a simple Lockable implementation that can be embedded into more complex structures

func NewSimpleLockable

func NewSimpleLockable(id NodeID, name string) SimpleLockable

func (*SimpleLockable) AddDependency

func (lockable *SimpleLockable) AddDependency(dependency Lockable)

func (*SimpleLockable) AddRequirement

func (lockable *SimpleLockable) AddRequirement(requirement Lockable)

func (*SimpleLockable) AllowedToTakeLock

func (lockable *SimpleLockable) AllowedToTakeLock(l Lockable, new_owner Lockable) bool

Nothing can take a lock from a simple lockable

func (*SimpleLockable) CanLock

func (lockable *SimpleLockable) CanLock(new_owner Lockable) error

func (*SimpleLockable) CanUnlock

func (lockable *SimpleLockable) CanUnlock(new_owner Lockable) error

func (*SimpleLockable) Dependencies

func (lockable *SimpleLockable) Dependencies() []Lockable

func (*SimpleLockable) Name

func (lockable *SimpleLockable) Name() string

func (*SimpleLockable) Owner

func (lockable *SimpleLockable) Owner() Lockable

func (*SimpleLockable) RecordLock

func (lockable *SimpleLockable) RecordLock(l Lockable, last_owner Lockable)

func (*SimpleLockable) RecordUnlock

func (lockable *SimpleLockable) RecordUnlock(l Lockable) Lockable

func (*SimpleLockable) RemoveDependency

func (lockable *SimpleLockable) RemoveDependency(dependency Lockable)

func (*SimpleLockable) RemoveRequirement

func (lockable *SimpleLockable) RemoveRequirement(requirement Lockable)

func (*SimpleLockable) Requirements

func (lockable *SimpleLockable) Requirements() []Lockable

func (*SimpleLockable) Serialize

func (lockable *SimpleLockable) Serialize() ([]byte, error)

func (*SimpleLockable) SetOwner

func (lockable *SimpleLockable) SetOwner(owner Lockable)

func (*SimpleLockable) Signal

func (lockable *SimpleLockable) Signal(ctx *Context, signal GraphSignal, nodes NodeMap) error

Lockable.Signal sends the update to the owner, requirements, and dependencies before updating listeners

func (*SimpleLockable) Type

func (state *SimpleLockable) Type() NodeType

type SimpleLockableJSON

type SimpleLockableJSON struct {
	Name         string             `json:"name"`
	Owner        *NodeID            `json:"owner"`
	Dependencies []NodeID           `json:"dependencies"`
	Requirements []NodeID           `json:"requirements"`
	LocksHeld    map[NodeID]*NodeID `json:"locks_held"`
}

func NewSimpleLockableJSON

func NewSimpleLockableJSON(lockable *SimpleLockable) SimpleLockableJSON

type SimpleThread

type SimpleThread struct {
	SimpleLockable

	InfoType reflect.Type
	// contains filtered or unexported fields
}

func NewSimpleThread

func NewSimpleThread(id NodeID, name string, state_name string, info_type reflect.Type, actions ThreadActions, handlers ThreadHandlers) SimpleThread

func (*SimpleThread) Action

func (thread *SimpleThread) Action(action string) (ThreadAction, bool)

func (*SimpleThread) AddChild

func (thread *SimpleThread) AddChild(child Thread, info ThreadInfo) error

func (*SimpleThread) Child

func (thread *SimpleThread) Child(id NodeID) Thread

func (*SimpleThread) ChildInfo

func (thread *SimpleThread) ChildInfo(child NodeID) ThreadInfo

func (*SimpleThread) ChildWaits

func (thread *SimpleThread) ChildWaits() *sync.WaitGroup

func (*SimpleThread) Children

func (thread *SimpleThread) Children() []Thread

func (*SimpleThread) ClearTimeout

func (thread *SimpleThread) ClearTimeout()

func (*SimpleThread) DeserializeInfo

func (thread *SimpleThread) DeserializeInfo(ctx *Context, data []byte) (ThreadInfo, error)

SimpleThread as no associated info with children

func (*SimpleThread) Handler

func (thread *SimpleThread) Handler(signal_type string) (ThreadHandler, bool)

func (*SimpleThread) Parent

func (thread *SimpleThread) Parent() Thread

func (*SimpleThread) RemoveChild

func (thread *SimpleThread) RemoveChild(child Thread)

func (*SimpleThread) Serialize

func (thread *SimpleThread) Serialize() ([]byte, error)

func (*SimpleThread) SetActive

func (thread *SimpleThread) SetActive(active bool) error

func (*SimpleThread) SetParent

func (thread *SimpleThread) SetParent(parent Thread)

func (*SimpleThread) SetState

func (thread *SimpleThread) SetState(new_state string) error

func (*SimpleThread) SetTimeout

func (thread *SimpleThread) SetTimeout(timeout time.Time, action string)

func (*SimpleThread) Signal

func (thread *SimpleThread) Signal(ctx *Context, signal GraphSignal, nodes NodeMap) error

SimpleThread.Signal updates the parent and children, and sends the signal to an internal channel

func (*SimpleThread) SignalChannel

func (thread *SimpleThread) SignalChannel() <-chan GraphSignal

func (*SimpleThread) State

func (thread *SimpleThread) State() string

func (*SimpleThread) Timeout

func (thread *SimpleThread) Timeout() <-chan time.Time

func (*SimpleThread) TimeoutAction

func (thread *SimpleThread) TimeoutAction() string

func (*SimpleThread) Type

func (thread *SimpleThread) Type() NodeType

type SimpleThreadJSON

type SimpleThreadJSON struct {
	Parent        *NodeID                `json:"parent"`
	Children      map[NodeID]interface{} `json:"children"`
	Timeout       time.Time              `json:"timeout"`
	TimeoutAction string                 `json:"timeout_action"`
	StateName     string                 `json:"state_name"`
	SimpleLockableJSON
}

func NewSimpleThreadJSON

func NewSimpleThreadJSON(thread *SimpleThread) SimpleThreadJSON

type Thread

type Thread interface {
	// All Threads are Lockables
	Lockable
	/// State Modification Functions
	SetParent(parent Thread)
	AddChild(child Thread, info ThreadInfo) error
	RemoveChild(child Thread)
	SetState(new_thread string) error
	SetTimeout(end_time time.Time, action string)
	/// State Reading Functions
	Parent() Thread
	Children() []Thread
	Child(id NodeID) Thread
	ChildInfo(child NodeID) ThreadInfo
	State() string
	TimeoutAction() string

	/// Functions that dont read/write thread
	// Deserialize the attribute map from json.Unmarshal
	DeserializeInfo(ctx *Context, data []byte) (ThreadInfo, error)
	SetActive(active bool) error
	Action(action string) (ThreadAction, bool)
	Handler(signal_type string) (ThreadHandler, bool)

	// Internal timeout channel for thread
	Timeout() <-chan time.Time
	// Internal signal channel for thread
	SignalChannel() <-chan GraphSignal
	ClearTimeout()

	ChildWaits() *sync.WaitGroup
}

func FindChild

func FindChild(ctx *Context, thread Thread, id NodeID, nodes NodeMap) Thread

Requires that thread is already locked for read in UseStates

type ThreadAbortedError

type ThreadAbortedError NodeID

func NewThreadAbortedError

func NewThreadAbortedError(aborter NodeID) ThreadAbortedError

func (ThreadAbortedError) Error

func (e ThreadAbortedError) Error() string

func (ThreadAbortedError) Is

func (e ThreadAbortedError) Is(target error) bool

type ThreadAction

type ThreadAction func(*Context, Thread) (string, error)

type ThreadActions

type ThreadActions map[string]ThreadAction

func NewThreadActions

func NewThreadActions() ThreadActions

type ThreadHandler

type ThreadHandler func(*Context, Thread, GraphSignal) (string, error)

type ThreadHandlers

type ThreadHandlers map[string]ThreadHandler

func NewThreadHandlers

func NewThreadHandlers() ThreadHandlers

type ThreadInfo

type ThreadInfo interface {
}

Interface to represent any type of thread information

Jump to

Keyboard shortcuts

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