From 6a0a0762ad8d4c92ce0b02583f052762d97b80fb Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Sun, 9 Jul 2023 20:30:19 -0600 Subject: [PATCH] Finished rework of context --- context.go | 4 +- gql.go | 34 +++++++--- gql_graph.go | 184 ++++++++++++++++++++++----------------------------- gql_test.go | 105 ++++++++++++++++------------- lockable.go | 1 + thread.go | 3 +- 6 files changed, 167 insertions(+), 164 deletions(-) diff --git a/context.go b/context.go index 83d8419..4a942cf 100644 --- a/context.go +++ b/context.go @@ -195,10 +195,10 @@ func NewContext(db * badger.DB, log Logger, extra_nodes map[string]NodeLoadFunc, if err != nil { panic(err) } - /*err := ctx.RegisterNodeType("gql_thread", LoadGQLThread) + err = ctx.RegisterNodeType("gql_thread", LoadGQLThread) if err != nil { panic(err) - }*/ + } for name, load_fn := range(extra_nodes) { err := ctx.RegisterNodeType(name, load_fn) diff --git a/gql.go b/gql.go index 7397037..560060e 100644 --- a/gql.go +++ b/gql.go @@ -344,17 +344,20 @@ func (thread * GQLThread) Serialize() ([]byte, error) { return json.MarshalIndent(&thread_json, "", " ") } +func (thread * GQLThread) DeserializeInfo(ctx *Context, data []byte) (ThreadInfo, error) { + var info GQLThreadInfo + err := json.Unmarshal(data, &info) + if err != nil { + return nil, err + } + return &info, nil +} + type GQLThreadJSON struct { SimpleThreadJSON Listen string `json:"listen"` } -type GQLThreadInfo struct { - Start bool `json:"start"` - StartAction string `json:"start_action"` - RestoreAction string `json:"restore_action"` -} - func NewGQLThreadJSON(thread *GQLThread) GQLThreadJSON { thread_json := NewSimpleThreadJSON(&thread.SimpleThread) @@ -364,6 +367,20 @@ func NewGQLThreadJSON(thread *GQLThread) GQLThreadJSON { } } +type GQLThreadInfo struct { + Start bool `json:"start"` + StartAction string `json:"start_action"` + RestoreAction string `json:"restore_action"` +} + +func NewGQLThreadInfo(start bool, start_action string, restore_action string) GQLThreadInfo { + return GQLThreadInfo{ + Start: start, + StartAction: start_action, + RestoreAction: restore_action, + } +} + func LoadGQLThread(ctx *Context, id NodeID, data []byte, nodes NodeMap) (Node, error) { var j GQLThreadJSON err := json.Unmarshal(data, &j) @@ -386,6 +403,7 @@ func NewGQLThread(id NodeID, name string, state_name string, listen string) GQLT return GQLThread{ SimpleThread: NewSimpleThread(id, name, state_name, reflect.TypeOf((*GQLThreadInfo)(nil)), gql_actions, gql_handlers), Listen: listen, + http_done: &sync.WaitGroup{}, } } @@ -479,14 +497,14 @@ var gql_handlers ThreadHandlers = ThreadHandlers{ server := thread.(*GQLThread) server.http_server.Shutdown(context.TODO()) server.http_done.Wait() - return "", NewThreadAbortedError(signal.Source()) + return ThreadAbort(ctx, thread, signal) }, "cancel": func(ctx * Context, thread Thread, signal GraphSignal) (string, error) { ctx.Log.Logf("gql", "GQL_CANCEL") server := thread.(*GQLThread) server.http_server.Shutdown(context.TODO()) server.http_done.Wait() - return "", nil + return ThreadCancel(ctx, thread, signal) }, } diff --git a/gql_graph.go b/gql_graph.go index e417ea2..7df4d2f 100644 --- a/gql_graph.go +++ b/gql_graph.go @@ -7,12 +7,12 @@ import ( ) var gql_interface_graph_node *graphql.Interface = nil -func GQLInterfaceGraphNode() *graphql.Interface { +func GQLInterfaceNode() *graphql.Interface { if gql_interface_graph_node == nil { gql_interface_graph_node = graphql.NewInterface(graphql.InterfaceConfig{ - Name: "GraphNode", + Name: "Node", ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return nil } @@ -39,10 +39,6 @@ func GQLInterfaceGraphNode() *graphql.Interface { gql_interface_graph_node.AddFieldConfig("ID", &graphql.Field{ Type: graphql.String, }) - - gql_interface_graph_node.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - }) } return gql_interface_graph_node @@ -62,7 +58,7 @@ func GQLInterfaceThread() *graphql.Interface { gql_interface_thread = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Thread", ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return nil } @@ -133,7 +129,7 @@ func GQLInterfaceLockable() *graphql.Interface { gql_interface_lockable = graphql.NewInterface(graphql.InterfaceConfig{ Name: "Lockable", ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return nil } @@ -186,27 +182,27 @@ func GQLInterfaceLockable() *graphql.Interface { } func GQLNodeID(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(GraphNode) + node, ok := p.Source.(Node) if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to GraphNode") + return nil, fmt.Errorf("Failed to cast source to Node") } return node.ID(), nil } -func GQLNodeName(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(GraphNode) +func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(*GQLThread) if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to GraphNode") + return nil, fmt.Errorf("Failed to cast source to GQLThread") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } - name := "" - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - name = states[node.ID()].Name() + listen := "" + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + listen = node.Listen return nil }) @@ -214,27 +210,23 @@ func GQLNodeName(p graphql.ResolveParams) (interface{}, error) { return nil, err } - return name, nil + return listen, nil } -func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(*GQLThread) +func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Thread) if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to GQLThread") + return nil, fmt.Errorf("Failed to cast source to Thread") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } - listen := "" - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(*GQLThreadState) - if ok == false { - return fmt.Errorf("Failed to cast state to GQLThreadState") - } - listen = gql_thread.Listen + var parent Thread = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + parent = node.Parent() return nil }) @@ -242,27 +234,23 @@ func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) { return nil, err } - return listen, nil + return parent, nil } -func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) { +func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) { node, ok := p.Source.(Thread) if ok == false || node == nil { return nil, fmt.Errorf("Failed to cast source to Thread") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } - var parent Thread = nil - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(ThreadState) - if ok == false { - return fmt.Errorf("Failed to cast state to ThreadState") - } - parent = gql_thread.Parent() + var children []Thread = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + children = node.Children() return nil }) @@ -270,27 +258,23 @@ func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) { return nil, err } - return parent, nil + return children, nil } -func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Thread) +func GQLLockableName(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Lockable) if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Thread") + return nil, fmt.Errorf("Failed to cast source to Lockable") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } - var children []Thread = nil - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(ThreadState) - if ok == false { - return fmt.Errorf("Failed to cast state to ThreadState") - } - children = gql_thread.Children() + name := "" + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) error { + name = node.Name() return nil }) @@ -298,7 +282,7 @@ func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) { return nil, err } - return children, nil + return name, nil } func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error) { @@ -307,18 +291,14 @@ func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error) { return nil, fmt.Errorf("Failed to cast source to Lockable") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } var requirements []Lockable = nil - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(LockableState) - if ok == false { - return fmt.Errorf("Failed to cast state to LockableState") - } - requirements = gql_thread.Requirements() + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + requirements = node.Requirements() return nil }) @@ -335,18 +315,14 @@ func GQLLockableDependencies(p graphql.ResolveParams) (interface{}, error) { return nil, fmt.Errorf("Failed to cast source to Lockable") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } var dependencies []Lockable = nil - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(LockableState) - if ok == false { - return fmt.Errorf("Failed to cast state to LockableState") - } - dependencies = gql_thread.Dependencies() + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + dependencies = node.Dependencies() return nil }) @@ -363,18 +339,14 @@ func GQLLockableOwner(p graphql.ResolveParams) (interface{}, error) { return nil, fmt.Errorf("Failed to cast source to Lockable") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext") + return nil, fmt.Errorf("Failed to cast context graph_context to Context") } - var owner GraphNode = nil - err := UseStates(ctx, []GraphNode{node}, func(states NodeStateMap) (error) { - gql_thread, ok := states[node.ID()].(LockableState) - if ok == false { - return fmt.Errorf("Failed to cast state to LockableState") - } - owner = gql_thread.Owner() + var owner Node = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + owner = node.Owner() return nil }) @@ -392,7 +364,7 @@ func GQLTypeGQLThread() * graphql.Object { gql_type_gql_thread = graphql.NewObject(graphql.ObjectConfig{ Name: "GQLThread", Interfaces: []*graphql.Interface{ - GQLInterfaceGraphNode(), + GQLInterfaceNode(), GQLInterfaceThread(), GQLInterfaceLockable(), }, @@ -410,7 +382,7 @@ func GQLTypeGQLThread() * graphql.Object { gql_type_gql_thread.AddFieldConfig("Name", &graphql.Field{ Type: graphql.String, - Resolve: GQLNodeName, + Resolve: GQLLockableName, }) gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{ @@ -452,12 +424,12 @@ func GQLTypeBaseThread() * graphql.Object { gql_type_base_thread = graphql.NewObject(graphql.ObjectConfig{ Name: "BaseThread", Interfaces: []*graphql.Interface{ - GQLInterfaceGraphNode(), + GQLInterfaceNode(), GQLInterfaceThread(), GQLInterfaceLockable(), }, IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return false } @@ -481,7 +453,7 @@ func GQLTypeBaseThread() * graphql.Object { gql_type_base_thread.AddFieldConfig("Name", &graphql.Field{ Type: graphql.String, - Resolve: GQLNodeName, + Resolve: GQLLockableName, }) gql_type_base_thread.AddFieldConfig("Children", &graphql.Field{ @@ -518,11 +490,11 @@ func GQLTypeBaseLockable() * graphql.Object { gql_type_base_lockable = graphql.NewObject(graphql.ObjectConfig{ Name: "BaseLockable", Interfaces: []*graphql.Interface{ - GQLInterfaceGraphNode(), + GQLInterfaceNode(), GQLInterfaceLockable(), }, IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return false } @@ -546,7 +518,7 @@ func GQLTypeBaseLockable() * graphql.Object { gql_type_base_lockable.AddFieldConfig("Name", &graphql.Field{ Type: graphql.String, - Resolve: GQLNodeName, + Resolve: GQLLockableName, }) gql_type_base_lockable.AddFieldConfig("Requirements", &graphql.Field{ @@ -573,10 +545,10 @@ func GQLTypeBaseNode() * graphql.Object { gql_type_base_node = graphql.NewObject(graphql.ObjectConfig{ Name: "BaseNode", Interfaces: []*graphql.Interface{ - GQLInterfaceGraphNode(), + GQLInterfaceNode(), }, IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { return false } @@ -600,7 +572,7 @@ func GQLTypeBaseNode() * graphql.Object { gql_type_base_node.AddFieldConfig("Name", &graphql.Field{ Type: graphql.String, - Resolve: GQLNodeName, + Resolve: GQLLockableName, }) } @@ -699,32 +671,32 @@ func GQLTypeSignalInput() *graphql.InputObject { } func GQLSubscribeSignal(p graphql.ResolveParams) (interface{}, error) { - return GQLSubscribeFn(p, false, func(ctx *GraphContext, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { + return GQLSubscribeFn(p, false, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { return signal, nil }) } func GQLSubscribeSelf(p graphql.ResolveParams) (interface{}, error) { - return GQLSubscribeFn(p, true, func(ctx *GraphContext, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { + return GQLSubscribeFn(p, true, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { return server, nil }) } -func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*GraphContext, *GQLThread, GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { +func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*Context, *GQLThread, GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { server, ok := p.Context.Value("gql_server").(*GQLThread) if ok == false { return nil, fmt.Errorf("Failed to get gql_server from context and cast to GQLServer") } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to get graph_context from context and cast to GraphContext") + return nil, fmt.Errorf("Failed to get graph_context from context and cast to Context") } c := make(chan interface{}) go func(c chan interface{}, server *GQLThread) { ctx.Log.Logf("gqlws", "GQL_SUBSCRIBE_THREAD_START") - sig_c := server.UpdateChannel(1) + sig_c := UpdateChannel(server, 1, RandID()) if send_nil == true { sig_c <- nil } @@ -793,9 +765,9 @@ func GQLMutationSendUpdate() *graphql.Field { return nil, fmt.Errorf("Failed to cast context gql_server to GQLServer: %+v", p.Context.Value("gql_server")) } - ctx, ok := p.Context.Value("graph_context").(*GraphContext) + ctx, ok := p.Context.Value("graph_context").(*Context) if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to GraphContext: %+v", p.Context.Value("graph_context")) + return nil, fmt.Errorf("Failed to cast context graph_context to Context: %+v", p.Context.Value("graph_context")) } signal_map, ok := p.Args["signal"].(map[string]interface{}) @@ -818,13 +790,13 @@ func GQLMutationSendUpdate() *graphql.Field { return nil, fmt.Errorf("Failed to cast arg id to string") } - var node GraphNode = nil - err := UseStates(ctx, []GraphNode{server}, func(states NodeStateMap) (error){ - node = FindChild(ctx, server, NodeID(id), states) + var node Node = nil + err := UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){ + node = FindChild(ctx, server, NodeID(id), nodes) if node == nil { return fmt.Errorf("Failed to find ID: %s as child of server thread", id) } - SendUpdate(ctx, node, signal, states) + node.Signal(ctx, signal, nodes) return nil }) if err != nil { diff --git a/gql_test.go b/gql_test.go index e6b6892..99eac62 100644 --- a/gql_test.go +++ b/gql_test.go @@ -4,64 +4,74 @@ import ( "testing" "time" "fmt" - "encoding/json" "errors" ) func TestGQLThread(t * testing.T) { ctx := logTestContext(t, []string{}) - gql_thread, err := NewGQLThread(ctx, ":0", []Lockable{}) - fatalErr(t, err) - - test_thread_1, err := NewSimpleThread(ctx, "Test thread 1", []Lockable{}, BaseThreadActions, BaseThreadHandlers) - fatalErr(t, err) - - test_thread_2, err := NewSimpleThread(ctx, "Test thread 2", []Lockable{}, BaseThreadActions, BaseThreadHandlers) - fatalErr(t, err) - - i1 := NewGQLThreadInfo(true, "start", "restore") - err = LinkThreads(ctx, gql_thread, test_thread_1, &i1) - fatalErr(t, err) + gql_t_r := NewGQLThread(RandID(), "GQL Thread", "init", ":0") + gql_t := &gql_t_r + + t1_r := NewSimpleThread(RandID(), "Test thread 1", "init", nil, BaseThreadActions, BaseThreadHandlers) + t1 := &t1_r + t2_r := NewSimpleThread(RandID(), "Test thread 2", "init", nil, BaseThreadActions, BaseThreadHandlers) + t2 := &t2_r + + err := UpdateStates(ctx, []Node{gql_t, t1, t2}, func(nodes NodeMap) error { + i1 := NewGQLThreadInfo(true, "start", "restore") + err := LinkThreads(ctx, gql_t, t1, &i1, nodes) + if err != nil { + return err + } - i2 := NewGQLThreadInfo(false, "start", "restore") - err = LinkThreads(ctx, gql_thread, test_thread_2, &i2) + i2 := NewGQLThreadInfo(false, "start", "restore") + return LinkThreads(ctx, gql_t, t2, &i2, nodes) + }) fatalErr(t, err) go func(thread Thread){ time.Sleep(10*time.Millisecond) - err := UseStates(ctx, []GraphNode{thread}, func(states NodeStateMap) error { - SendUpdate(ctx, thread, CancelSignal(nil), states) - return nil + err := UseStates(ctx, []Node{thread}, func(nodes NodeMap) error { + return thread.Signal(ctx, CancelSignal(nil), nodes) }) fatalErr(t, err) - }(gql_thread) + }(gql_t) - err = ThreadLoop(ctx, gql_thread, "start") + err = ThreadLoop(ctx, gql_t, "start") fatalErr(t, err) } func TestGQLDBLoad(t * testing.T) { - ctx := logTestContext(t, []string{"thread", "update", "gql"}) - l1, err := NewSimpleLockable(ctx, "Test Lockable 1", []Lockable{}) - fatalErr(t, err) + ctx := logTestContext(t, []string{"thread", "signal", "gql", "test"}) + l1_r := NewSimpleLockable(RandID(), "Test Lockable 1") + l1 := &l1_r - t1, err := NewSimpleThread(ctx, "Test Thread 1", []Lockable{}, BaseThreadActions, BaseThreadHandlers) - fatalErr(t, err) - update_channel := t1.UpdateChannel(10) + t1_r := NewSimpleThread(RandID(), "Test Thread 1", "init", nil, BaseThreadActions, BaseThreadHandlers) + t1 := &t1_r + update_channel := UpdateChannel(t1, 10, "test") - gql, err := NewGQLThread(ctx, ":0", []Lockable{l1}) - fatalErr(t, err) + gql_r := NewGQLThread(RandID(), "GQL Thread", "init", ":8080") + gql := &gql_r info := NewGQLThreadInfo(true, "start", "restore") - err = UpdateStates(ctx, []GraphNode{gql, t1}, func(nodes NodeMap) error { - return LinkThreads(ctx, gql, t1, &info) + err := UpdateStates(ctx, []Node{gql, t1}, func(nodes NodeMap) error { + err := LinkLockables(ctx, gql, []Lockable{l1}, nodes) + if err != nil { + return err + } + return LinkThreads(ctx, gql, t1, &info, nodes) }) fatalErr(t, err) - err = UseStates(ctx, []GraphNode{gql}, func(states NodeStateMap) error { - SendUpdate(ctx, gql, NewSignal(t1, "child_added"), states) - SendUpdate(ctx, gql, AbortSignal(nil), states) - return nil + + err = UseStates(ctx, []Node{gql}, func(nodes NodeMap) error { + err := gql.Signal(ctx, NewSignal(t1, "child_added"), nodes) + if err != nil { + return nil + } + return gql.Signal(ctx, AbortSignal(nil), nodes) }) + fatalErr(t, err) + err = ThreadLoop(ctx, gql, "start") if errors.Is(err, NewThreadAbortedError("")) { ctx.Log.Logf("test", "Main thread aborted by signal: %s", err) @@ -71,9 +81,9 @@ func TestGQLDBLoad(t * testing.T) { (*GraphTester)(t).WaitForValue(ctx, update_channel, "thread_aborted", t1, 100*time.Millisecond, "Didn't receive thread_abort from t1 on t1") - err = UseStates(ctx, []GraphNode{gql, t1}, func(states NodeStateMap) error { - ser1, err := json.MarshalIndent(states[gql.ID()], "", " ") - ser2, err := json.MarshalIndent(states[t1.ID()], "", " ") + err = UseStates(ctx, []Node{gql, t1}, func(nodes NodeMap) error { + ser1, err := gql.Serialize() + ser2, err := t1.Serialize() fmt.Printf("\n%s\n\n", ser1) fmt.Printf("\n%s\n\n", ser2) return err @@ -81,20 +91,21 @@ func TestGQLDBLoad(t * testing.T) { gql_loaded, err := LoadNode(ctx, gql.ID()) fatalErr(t, err) - var t1_loaded *BaseThread = nil + var t1_loaded *SimpleThread = nil - err = UseStates(ctx, []GraphNode{gql_loaded}, func(states NodeStateMap) error { - ser, err := json.MarshalIndent(states[gql_loaded.ID()], "", " ") + var update_channel_2 chan GraphSignal + err = UseStates(ctx, []Node{gql_loaded}, func(nodes NodeMap) error { + ser, err := gql_loaded.Serialize() fmt.Printf("\n%s\n\n", ser) - child := states[gql_loaded.ID()].(ThreadState).Children()[0] - t1_loaded = child.(*BaseThread) - update_channel = t1_loaded.UpdateChannel(10) - err = UseMoreStates(ctx, []GraphNode{child}, states, func(states NodeStateMap) error { - ser, err := json.MarshalIndent(states[child.ID()], "", " ") + child := gql_loaded.(Thread).Children()[0].(*SimpleThread) + t1_loaded = child + update_channel_2 = UpdateChannel(t1_loaded, 10, "test") + err = UseMoreStates(ctx, []Node{child}, nodes, func(nodes NodeMap) error { + ser, err := child.Serialize() fmt.Printf("\n%s\n\n", ser) return err }) - SendUpdate(ctx, gql_loaded, AbortSignal(nil), states) + gql_loaded.Signal(ctx, AbortSignal(nil), nodes) return err }) @@ -104,6 +115,6 @@ func TestGQLDBLoad(t * testing.T) { } else { fatalErr(t, err) } - (*GraphTester)(t).WaitForValue(ctx, update_channel, "thread_aborted", t1_loaded, 100*time.Millisecond, "Dicn't received thread_aborted on t1_loaded from t1_loaded") + (*GraphTester)(t).WaitForValue(ctx, update_channel_2, "thread_aborted", t1_loaded, 100*time.Millisecond, "Dicn't received thread_aborted on t1_loaded from t1_loaded") } diff --git a/lockable.go b/lockable.go index e4a35c5..5a79dd3 100644 --- a/lockable.go +++ b/lockable.go @@ -27,6 +27,7 @@ type Lockable interface { 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 diff --git a/thread.go b/thread.go index 137915c..db2f133 100644 --- a/thread.go +++ b/thread.go @@ -145,7 +145,7 @@ func (thread * SimpleThread) AddChild(child Thread, info ThreadInfo) error { return fmt.Errorf("nil info passed when expecting info") } else if info != nil { if reflect.TypeOf(info) != thread.InfoType { - return fmt.Errorf("info type mismatch, expecting %+v", thread.InfoType) + return fmt.Errorf("info type mismatch, expecting %+v - %+v", thread.InfoType, reflect.TypeOf(info)) } } @@ -388,6 +388,7 @@ const THREAD_SIGNAL_BUFFER_SIZE = 128 func NewSimpleThread(id NodeID, name string, state_name string, info_type reflect.Type, actions ThreadActions, handlers ThreadHandlers) SimpleThread { return SimpleThread{ SimpleLockable: NewSimpleLockable(id, name), + InfoType: info_type, state_name: state_name, signal: make(chan GraphSignal, THREAD_SIGNAL_BUFFER_SIZE), children: []Thread{},