Made event part of the closure and created first step of match

graph-rework
noah metz 2023-05-30 21:50:59 -06:00
parent 62dbe54e81
commit b7365f7dfb
6 changed files with 151 additions and 38 deletions

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"log"
"errors" "errors"
graphql "github.com/graph-gophers/graphql-go" graphql "github.com/graph-gophers/graphql-go"
"reflect" "reflect"
@ -73,7 +74,7 @@ type BaseEvent struct {
required_resources []Resource required_resources []Resource
children []Event children []Event
child_info map[Event]EventInfo child_info map[Event]EventInfo
actions map[string]func(Event) (string, error) actions map[string]func() (string, error)
parent Event parent Event
signal chan string signal chan string
abort chan string abort chan string
@ -138,7 +139,7 @@ func (event * BaseEvent) Run() error {
} }
// Run the edge function // Run the edge function
next_action, err = action(event) next_action, err = action()
if err != nil { if err != nil {
return err return err
} else if next_action == "wait" { } else if next_action == "wait" {
@ -184,7 +185,7 @@ func NewBaseEvent(name string, description string, required_resources []Resource
child_info: map[Event]EventInfo{}, child_info: map[Event]EventInfo{},
done_resource: done_resource, done_resource: done_resource,
required_resources: required_resources, required_resources: required_resources,
actions: map[string]func(Event)(string, error){}, actions: map[string]func()(string, error){},
signal: make(chan string, 10), signal: make(chan string, 10),
abort: make(chan string, 1), abort: make(chan string, 1),
} }
@ -199,7 +200,7 @@ func NewEvent(name string, description string, required_resources []Resource) (*
// Lock the done_resource by default // Lock the done_resource by default
event.LockDone() event.LockDone()
event_ptr.actions["start"] = func(event Event) (string, error) { event_ptr.actions["start"] = func() (string, error) {
return "", nil return "", nil
} }
@ -214,11 +215,13 @@ func NewEventQueue(name string, description string, required_resources []Resourc
// Need to lock it with th BaseEvent since Unlock is implemented on the BaseEvent // Need to lock it with th BaseEvent since Unlock is implemented on the BaseEvent
queue.LockDone() queue.LockDone()
queue.actions["start"] = func(queue Event) (string, error) { queue.actions["start"] = func() (string, error) {
log.Printf("Starting Event Queue")
return "queue_event", nil return "queue_event", nil
} }
queue.actions["queue_event"] = func(queue Event) (string, error) { queue.actions["queue_event"] = func() (string, error) {
log.Printf("Queueing events")
// Copy the events to sort the list // Copy the events to sort the list
copied_events := make([]Event, len(queue.Children())) copied_events := make([]Event, len(queue.Children()))
copy(copied_events, queue.Children()) copy(copied_events, queue.Children())
@ -260,11 +263,18 @@ func NewEventQueue(name string, description string, required_resources []Resourc
} }
} }
queue.actions["event_done"] = func(queue Event) (string, error) { queue.actions["event_done"] = func() (string, error) {
log.Printf("event_done")
return "queue_event", nil return "queue_event", nil
} }
queue.actions["resource_available"] = func(queue Event) (string, error) { queue.actions["resource_available"] = func() (string, error) {
log.Printf("resources_available")
return "queue_event", nil
}
queue.actions["event_added"] = func() (string, error) {
log.Printf("event_added")
return "queue_event", nil return "queue_event", nil
} }

@ -4,42 +4,114 @@ import (
"log" "log"
) )
func fake_team(org string, id string, names []string) (*Team, []*Member) {
members := []*Member{}
for _, name := range(names) {
members = append(members, NewMember(name))
}
team := NewTeam(org, id, members)
return team, members
}
func fake_data() * EventManager { func fake_data() * EventManager {
resources := []Resource{} resources := []Resource{}
teams := []*Team{} teams := []*Team{}
teams = append(teams, NewTeam("6659", "A", []*Member{NewMember("jimmy")})) t1, m1 := fake_team("6659", "A", []string{"jimmy"})
teams = append(teams, NewTeam("6659", "B", []*Member{NewMember("timmy")})) t2, m2 := fake_team("6659", "B", []string{"timmy"})
teams = append(teams, NewTeam("6659", "C", []*Member{NewMember("grace")})) t3, m3 := fake_team("6659", "C", []string{"grace"})
teams = append(teams, NewTeam("6659", "D", []*Member{NewMember("jeremy")})) t4, m4 := fake_team("6659", "D", []string{"jeremy"})
teams = append(teams, NewTeam("210", "W", []*Member{NewMember("bobby")})) t5, m5 := fake_team("210", "W", []string{"bobby"})
teams = append(teams, NewTeam("210", "X", []*Member{NewMember("toby")})) t6, m6 := fake_team("210", "X", []string{"toby"})
teams = append(teams, NewTeam("210", "Y", []*Member{NewMember("jennifer")})) t7, m7 := fake_team("210", "Y", []string{"jennifer"})
teams = append(teams, NewTeam("210", "Z", []*Member{NewMember("emily")})) t8, m8 := fake_team("210", "Z", []string{"emily"})
teams = append(teams, NewTeam("315", "W", []*Member{NewMember("bobby")})) t9, m9 := fake_team("315", "W", []string{"bobby"})
teams = append(teams, NewTeam("315", "X", []*Member{NewMember("toby")})) t10, m10 := fake_team("315", "X", []string{"toby"})
teams = append(teams, NewTeam("315", "Y", []*Member{NewMember("jennifer")})) t11, m11 := fake_team("315", "Y", []string{"jennifer"})
teams = append(teams, NewTeam("315", "Z", []*Member{NewMember("emily")})) t12, m12 := fake_team("315", "Z", []string{"emily"})
for _, team := range teams { teams = append(teams, t1)
resources = append(resources, team) teams = append(teams, t2)
} teams = append(teams, t3)
teams = append(teams, t4)
teams = append(teams, t5)
teams = append(teams, t6)
teams = append(teams, t7)
teams = append(teams, t8)
teams = append(teams, t9)
teams = append(teams, t10)
teams = append(teams, t11)
teams = append(teams, t12)
resources = append(resources, m1[0])
resources = append(resources, m2[0])
resources = append(resources, m3[0])
resources = append(resources, m4[0])
resources = append(resources, m5[0])
resources = append(resources, m6[0])
resources = append(resources, m7[0])
resources = append(resources, m8[0])
resources = append(resources, m9[0])
resources = append(resources, m10[0])
resources = append(resources, m11[0])
resources = append(resources, m12[0])
alliances := []*Alliance{}
for i, team := range teams[:len(teams)-1] { for i, team := range teams[:len(teams)-1] {
for _, team2 := range teams[i+1:] { for _, team2 := range teams[i+1:] {
alliance := NewAlliance(team, team2) alliance := NewAlliance(team, team2)
resources = append(resources, alliance) alliances = append(alliances, alliance)
} }
} }
root_event := NewEventQueue("root_event", "", []Resource{}) arenas := []*Arena{}
arenas = append(arenas, NewVirtualArena("Arena 1"))
arenas = append(arenas, NewVirtualArena("Arena 2"))
arenas = append(arenas, NewVirtualArena("Arena 3"))
for _, arena := range arenas {
resources = append(resources, arena)
}
for _, team := range teams {
resources = append(resources, team)
}
for _, alliance := range alliances {
resources = append(resources, alliance)
}
root_event := NewEventQueue("root_event", "", []Resource{})
event_manager := NewEventManager(root_event, resources) event_manager := NewEventManager(root_event, resources)
arena_idx := 0
for i, alliance := range alliances[:len(alliances)-1] {
for _, alliance2 := range alliances[i+1:] {
match := NewMatch(alliance, alliance2, arenas[arena_idx])
err := event_manager.AddEvent(root_event, match, NewEventQueueInfo(i))
if err != nil {
log.Printf("Error adding %s: %s", match.Name(), err)
}
arena_idx += 1
if arena_idx >= len(arenas) {
arena_idx = 0
}
}
}
return event_manager return event_manager
} }
func main() { func main() {
event_manager := fake_data() event_manager := fake_data()
log.Printf("Starting event_manager: %+v", event_manager) log.Printf("Starting event_manager")
err := event_manager.Run()
if err != nil {
log.Printf("Error running event_manager: %s", err)
} else {
log.Printf("Finished event_manager")
}
} }

@ -24,12 +24,15 @@ func NewEventManager(root_event Event, dag_nodes []Resource) * EventManager {
for _, resource := range dag_nodes { for _, resource := range dag_nodes {
err := manager.AddResource(resource) err := manager.AddResource(resource)
if err != nil { if err != nil {
log.Printf("Failed to add %s to EventManager: %s", resource.ID(), err) log.Printf("Failed to add %s to EventManager: %s", resource.Name(), err)
return nil return nil
} }
} }
manager.AddEvent(nil, root_event, nil) err := manager.AddEvent(nil, root_event, nil)
if err != nil {
log.Printf("Failed to add %s to EventManager as root_event: %s", root_event.Name(), err)
}
return manager; return manager;
} }
@ -56,14 +59,14 @@ func (manager * EventManager) FindEvent(id graphql.ID) Event {
func (manager * EventManager) AddResource(resource Resource) error { func (manager * EventManager) AddResource(resource Resource) error {
_, exists := manager.dag_nodes[resource.ID()] _, exists := manager.dag_nodes[resource.ID()]
if exists == true { if exists == true {
error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again", resource.ID()) error_str := fmt.Sprintf("%s is already in the resource DAG, cannot add again", resource.Name())
return errors.New(error_str) return errors.New(error_str)
} }
for _, child := range resource.Children() { for _, child := range resource.Children() {
_, exists := manager.dag_nodes[child.ID()] _, exists := manager.dag_nodes[child.ID()]
if exists == false { if exists == false {
error_str := fmt.Sprintf("%s is not in the resource DAG, cannot add %s to DAG", child.ID(), resource.ID()) error_str := fmt.Sprintf("%s is not in the resource DAG, cannot add %s to DAG", child.Name(), resource.Name())
return errors.New(error_str) return errors.New(error_str)
} }
} }

@ -330,9 +330,12 @@ func TestStartEventQueue(t * testing.T) {
root_event := NewEventQueue("", "", []Resource{}) root_event := NewEventQueue("", "", []Resource{})
r := root_event.DoneResource() r := root_event.DoneResource()
rel := root_event.UpdateChannel(); rel := root_event.UpdateChannel();
manager := NewEventManager(root_event, []Resource{}) res_1 := NewResource("test_resource", "", []Resource{})
res_2 := NewResource("test_resource", "", []Resource{})
manager := NewEventManager(root_event, []Resource{res_1, res_2})
e1:= NewEvent("1", "", []Resource{}) e1:= NewEvent("1", "", []Resource{res_1, res_2})
e1_r := e1.DoneResource() e1_r := e1.DoneResource()
e1_info := NewEventQueueInfo(1) e1_info := NewEventQueueInfo(1)
err := manager.AddEvent(root_event, e1, e1_info) err := manager.AddEvent(root_event, e1, e1_info)
@ -341,7 +344,7 @@ func TestStartEventQueue(t * testing.T) {
} }
(*graph_tester)(t).CheckForNil(rel) (*graph_tester)(t).CheckForNil(rel)
e2 := NewEvent("1", "", []Resource{}) e2 := NewEvent("1", "", []Resource{res_1})
e2_r := e2.DoneResource() e2_r := e2.DoneResource()
e2_info := NewEventQueueInfo(2) e2_info := NewEventQueueInfo(2)
err = manager.AddEvent(root_event, e2, e2_info) err = manager.AddEvent(root_event, e2, e2_info)
@ -350,7 +353,7 @@ func TestStartEventQueue(t * testing.T) {
} }
(*graph_tester)(t).CheckForNil(rel) (*graph_tester)(t).CheckForNil(rel)
e3 := NewEvent("1", "", []Resource{}) e3 := NewEvent("1", "", []Resource{res_2})
e3_r := e3.DoneResource() e3_r := e3.DoneResource()
e3_info := NewEventQueueInfo(3) e3_info := NewEventQueueInfo(3)
err = manager.AddEvent(root_event, e3, e3_info) err = manager.AddEvent(root_event, e3, e3_info)

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"log"
) )
type ArenaDriver interface { type ArenaDriver interface {
@ -119,6 +120,7 @@ func NewAlliance(team0 * Team, team1 * Team) * Alliance {
type Match struct { type Match struct {
BaseEvent BaseEvent
state string
} }
func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match { func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match {
@ -127,11 +129,24 @@ func NewMatch(alliance0 * Alliance, alliance1 * Alliance, arena * Arena) * Match
match := &Match{ match := &Match{
BaseEvent: NewBaseEvent(name, description, []Resource{alliance0, alliance1, arena}), BaseEvent: NewBaseEvent(name, description, []Resource{alliance0, alliance1, arena}),
state: "init",
} }
match.LockDone() match.LockDone()
match.actions["start"] = func(match Event) (string, error) { match.actions["start"] = func() (string, error) {
return "", nil // put the match into "scheduled" state
log.Printf("Starting match")
match.state = "scheduled"
return "wait", nil
}
match.actions["start_autonomous"] = func() (string, error) {
if match.state != "scheduled" {
log.Printf("Cannot start_autonomous when the match is in %s", match.state)
return "wait", nil
}
log.Printf("Starting autonomous")
return "wait", nil
} }
return match return match

@ -3,6 +3,7 @@ package main
import ( import (
"testing" "testing"
"fmt" "fmt"
"time"
) )
type vex_tester graph_tester type vex_tester graph_tester
@ -98,7 +99,7 @@ func TestNewAllianceAdd(t *testing.T) {
} }
} }
func TestNewMatchAdd(t *testing.T) { func TestNewMatch(t *testing.T) {
name_1 := "Noah" name_1 := "Noah"
name_2 := "Ben" name_2 := "Ben"
name_3 := "Justin" name_3 := "Justin"
@ -132,5 +133,14 @@ func TestNewMatchAdd(t *testing.T) {
root_event := NewMatch(alliance_1, alliance_2, arena) root_event := NewMatch(alliance_1, alliance_2, arena)
event_manager := NewEventManager(root_event, []Resource{member_1, member_2, member_3, member_4, team_1, team_2, team_3, team_4, alliance_1, alliance_2, arena}) event_manager := NewEventManager(root_event, []Resource{member_1, member_2, member_3, member_4, team_1, team_2, team_3, team_4, alliance_1, alliance_2, arena})
println(event_manager)
go func() {
time.Sleep(time.Second * 2)
root_event.Abort()
}()
err := event_manager.Run()
if err == nil {
t.Fatal(err)
}
} }