reworked thread to use queue instead of single action

graph-rework-2
noah metz 2023-07-24 17:49:26 -06:00
parent 2e77b811d5
commit 3fa550ab29
1 changed files with 30 additions and 17 deletions

@ -160,8 +160,8 @@ func NewChildInfo(child ThreadNode, infos map[InfoType]interface{}) ChildInfo {
} }
type QueuedAction struct { type QueuedAction struct {
Timeout time.Time Timeout time.Time `json:"time"`
Action string Action string `json:"action"`
} }
type ThreadNode interface { type ThreadNode interface {
@ -185,9 +185,13 @@ type Thread struct {
Parent ThreadNode Parent ThreadNode
Children map[NodeID]ChildInfo Children map[NodeID]ChildInfo
InfoTypes []InfoType InfoTypes []InfoType
TimeoutAction string ActionQueue []QueuedAction
Timeout time.Time NextAction *QueuedAction
}
func (thread *Thread) QueueAction(end time.Time, action string) {
thread.ActionQueue = append(thread.ActionQueue, QueuedAction{end, action})
thread.NextAction, thread.TimeoutChan = thread.SoonestAction()
} }
func (thread *Thread) ThreadHandle() *Thread { func (thread *Thread) ThreadHandle() *Thread {
@ -216,8 +220,7 @@ func (thread *Thread) ChildList() []ThreadNode {
type ThreadJSON struct { type ThreadJSON struct {
Parent string `json:"parent"` Parent string `json:"parent"`
Children map[string]map[string]interface{} `json:"children"` Children map[string]map[string]interface{} `json:"children"`
Timeout time.Time `json:"timeout"` ActionQueue []QueuedAction `json:"action_queue"`
TimeoutAction string `json:"timeout_action"`
StateName string `json:"state_name"` StateName string `json:"state_name"`
LockableJSON LockableJSON
} }
@ -242,8 +245,7 @@ func NewThreadJSON(thread *Thread) ThreadJSON {
return ThreadJSON{ return ThreadJSON{
Parent: parent_id, Parent: parent_id,
Children: children, Children: children,
Timeout: thread.Timeout, ActionQueue: thread.ActionQueue,
TimeoutAction: thread.TimeoutAction,
StateName: thread.StateName, StateName: thread.StateName,
LockableJSON: lockable_json, LockableJSON: lockable_json,
} }
@ -267,11 +269,24 @@ func LoadThread(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, erro
return &thread, nil return &thread, nil
} }
func RestoreThread(ctx *Context, thread *Thread, j ThreadJSON, nodes NodeMap) error { func (thread *Thread) SoonestAction() (*QueuedAction, <-chan time.Time) {
if j.TimeoutAction != "" { var soonest_action *QueuedAction
thread.Timeout = j.Timeout var soonest_time time.Time
thread.TimeoutAction = j.TimeoutAction for _, action := range(thread.ActionQueue) {
if action.Timeout.Compare(soonest_time) == -1 {
soonest_action = &action
}
}
if soonest_action != nil {
return soonest_action, time.After(time.Until(soonest_action.Timeout))
} else {
return nil, nil
} }
}
func RestoreThread(ctx *Context, thread *Thread, j ThreadJSON, nodes NodeMap) error {
thread.ActionQueue = j.ActionQueue
thread.NextAction, thread.TimeoutChan = thread.SoonestAction()
if j.Parent != "" { if j.Parent != "" {
parent_id, err := ParseID(j.Parent) parent_id, err := ParseID(j.Parent)
@ -574,7 +589,7 @@ func ThreadStart(ctx * Context, node ThreadNode) (string, error) {
func ThreadWait(ctx * Context, node ThreadNode) (string, error) { func ThreadWait(ctx * Context, node ThreadNode) (string, error) {
thread := node.ThreadHandle() thread := node.ThreadHandle()
ctx.Log.Logf("thread", "THREAD_WAIT: %s TIMEOUT: %+v", thread.ID(), thread.Timeout) ctx.Log.Logf("thread", "THREAD_WAIT: %s", thread.ID())
for { for {
select { select {
case signal := <- thread.Chan: case signal := <- thread.Chan:
@ -590,10 +605,8 @@ func ThreadWait(ctx * Context, node ThreadNode) (string, error) {
timeout_action := "" timeout_action := ""
context := NewWriteContext(ctx) context := NewWriteContext(ctx)
err := UpdateStates(context, thread, NewLockMap(NewLockInfo(thread, []string{"timeout"})), func(context *StateContext) error { err := UpdateStates(context, thread, NewLockMap(NewLockInfo(thread, []string{"timeout"})), func(context *StateContext) error {
timeout_action = thread.TimeoutAction timeout_action = thread.NextAction.Action
thread.TimeoutChan = nil thread.NextAction, thread.TimeoutChan = thread.SoonestAction()
thread.TimeoutAction = ""
thread.Timeout = time.Time{}
return nil return nil
}) })
if err != nil { if err != nil {