diff --git a/event.go b/event.go index 314ec6a..13f49fc 100644 --- a/event.go +++ b/event.go @@ -6,19 +6,18 @@ import ( "errors" "reflect" "sort" - "sync" ) // Update the events listeners, and notify the parent to do the same -func (event * BaseEvent) Update(reason string) error { - log.Printf("UPDATE BaseEvent %s: %s", event.Name(), reason) - err := event.UpdateListeners(reason) - if err != nil { - return err - } +func (event * BaseEvent) Update(signal GraphSignal) error { + log.Printf("UPDATE BaseEvent %s: %+v", event.Name(), signal) + + event.signal <- signal + + event.BaseNode.Update(signal) if event.parent != nil{ - return event.parent.Update("update parent") + return event.parent.Update(signal) } return nil } @@ -58,7 +57,6 @@ type Event interface { FindChild(id string) Event Run() error Abort() error - Signal(action string) error LockResources() error Finish() error } @@ -76,32 +74,16 @@ type BaseEvent struct { children []Event child_info map[Event]EventInfo actions map[string]func() (string, error) + handlers map[string]func() (string, error) parent Event - signal chan string abort chan string } -func (queue * EventQueue) Abort() error { - for _, event := range(queue.children) { - event.Abort() - } - for _, c := range(queue.resource_aborts) { - c <- "event abort" - } - queue.signal <- "abort" - return nil -} - func (event * BaseEvent) Abort() error { for _, event := range(event.children) { event.Abort() } - event.signal <- "abort" - return nil -} - -func (event * BaseEvent) Signal(action string) error { - event.signal <- action + event.signal <- NewSignal(event, "abort") return nil } @@ -141,11 +123,17 @@ func (event * BaseEvent) Finish() error { } resource.NotifyUnlocked() } + err := event.DoneResource().Unlock(event) if err != nil { return err } - return event.DoneResource().NotifyUnlocked() + + err = event.DoneResource().NotifyUnlocked() + + event.Update(NewSignal(event, "event_done")) + + return err } func (event * BaseEvent) LockDone() { @@ -153,11 +141,11 @@ func (event * BaseEvent) LockDone() { } func (event * BaseEvent) Run() error { + log.Printf("EVENT_RUN: %s", event.Name()) next_action := "start" var err error = nil for next_action != "" { // Check if the edge exists - cur_action := next_action action, exists := event.actions[next_action] if exists == false { error_str := fmt.Sprintf("%s is not a valid action", next_action) @@ -165,37 +153,17 @@ func (event * BaseEvent) Run() error { } // Run the edge function + update_str := fmt.Sprintf("EVENT_ACTION: %s", next_action) + log.Printf(update_str) next_action, err = action() if err != nil { return err - } else if next_action == "wait" { - // Wait for an external signal to set the next_action - signal := <- event.signal - if signal == "abort" { - return errors.New("State Machine aborted by signal") - } else { - next_action = signal - } - } else { - // next_action is already set correctly } - - // Update the event after running the edge - update_str := fmt.Sprintf("ACTION %s: NEXT %s", cur_action, next_action) - event.Update(update_str) } return nil } -// EventQueue is a basic event that can have children. -// On start, it attempts to start it's children from the highest 'priority' -type EventQueue struct { - BaseEvent - resource_aborts map[string]chan string - resource_lock sync.Mutex -} - func NewBaseEvent(name string, description string, required_resources []Resource) (BaseEvent) { done_resource := NewResource("event_done", "signal that event is done", []Resource{}) event := BaseEvent{ @@ -203,7 +171,8 @@ func NewBaseEvent(name string, description string, required_resources []Resource name: name, description: description, id: randid(), - listeners: []chan string{}, + signal: make(chan GraphSignal, 10), + listeners: map[chan GraphSignal] chan GraphSignal{}, }, parent: nil, children: []Event{}, @@ -211,10 +180,26 @@ func NewBaseEvent(name string, description string, required_resources []Resource done_resource: done_resource, required_resources: required_resources, actions: map[string]func()(string, error){}, - signal: make(chan string, 10), + handlers: map[string]func()(string, error){}, abort: make(chan string, 1), } + event.actions["wait"] = func() (string, error) { + signal := <- event.signal + if signal.Type() == "abort" { + return "", errors.New("State machine aborted by signal") + } else if signal.Type() == "do_action" { + return signal.Description(), nil + } else { + signal_fn, exists := event.handlers[signal.Type()] + if exists == true { + return signal_fn() + } + } + // ignore signals other than "abort" and "do_action" + return "wait", nil + } + return event } @@ -232,10 +217,26 @@ func NewEvent(name string, description string, required_resources []Resource) (* return event_ptr } +// EventQueue is a basic event that can have children. +// On start, it attempts to start it's children from the highest 'priority' +type EventQueue struct { + BaseEvent + listened_resources map[string]Resource +} + +func (queue * EventQueue) Finish() error { + for _, resource := range(queue.listened_resources) { + resource.UnregisterChannel(queue.signal) + } + return queue.BaseEvent.Finish() +} + + + func NewEventQueue(name string, description string, required_resources []Resource) (* EventQueue) { queue := &EventQueue{ BaseEvent: NewBaseEvent(name, description, []Resource{}), - resource_aborts: map[string]chan string{}, + listened_resources: map[string]Resource{}, } // Need to lock it with th BaseEvent since Unlock is implemented on the BaseEvent @@ -257,42 +258,11 @@ func NewEventQueue(name string, description string, required_resources []Resourc sort.SliceStable(copied_events, less) wait := false + needed_resources := map[string]Resource{} for _, event := range(copied_events) { - // Update the resource_chans + // make sure all the required resources are registered to update the event for _, resource := range(event.RequiredResources()) { - queue.resource_lock.Lock() - _, exists := queue.resource_aborts[resource.ID()] - if exists == false { - log.Printf("RESOURCE_LISTENER_START: %s", resource.Name()) - abort := make(chan string, 1) - queue.resource_aborts[resource.ID()] = abort - go func(queue *EventQueue, resource Resource, abort chan string) { - log.Printf("RESOURCE_LISTENER_GOROUTINE: %s", resource.Name()) - resource_chan := resource.UpdateChannel() - for true { - select { - case <- abort: - queue.resource_lock.Lock() - delete(queue.resource_aborts, resource.ID()) - queue.resource_lock.Unlock() - log.Printf("RESORCE_LISTENER_ABORT: %s", resource.Name()) - break - case msg, ok := <- resource_chan: - if ok == false { - queue.resource_lock.Lock() - delete(queue.resource_aborts, resource.ID()) - queue.resource_lock.Unlock() - log.Printf("RESOURCE_LISTENER_CLOSED: %s : %s", resource.Name(), msg) - break - } - log.Printf("RESOURCE_LISTENER_UPDATED: %s : %s", resource.Name(), msg) - queue.signal <- "resource_update" - } - } - log.Printf("RESOURCE_LISTENER_DYING: %s", resource.Name()) - }(queue, resource, abort) - } - queue.resource_lock.Unlock() + needed_resources[resource.ID()] = resource } info := queue.ChildInfo(event).(*EventQueueInfo) @@ -313,7 +283,6 @@ func NewEventQueue(name string, description string, required_resources []Resourc } info.state = "done" event.Finish() - queue.Signal("event_done") }(event, info, queue) } } else if info.state == "running" { @@ -321,6 +290,11 @@ func NewEventQueue(name string, description string, required_resources []Resourc } } + for _, resource := range(needed_resources) { + queue.listened_resources[resource.ID()] = resource + resource.RegisterChannel(queue.signal) + } + if wait == true { return "wait", nil } else { @@ -340,6 +314,14 @@ func NewEventQueue(name string, description string, required_resources []Resourc return "queue_event", nil } + queue.handlers["lock_change"] = func() (string, error) { + return "queue_event", nil + } + + queue.handlers["event_done"] = func() (string, error) { + return "queue_event", nil + } + return queue } @@ -410,7 +392,7 @@ func (event * BaseEvent) addChild(child Event, info EventInfo) error { event.children = append(event.children, child) event.child_info[child] = info - event.Update("child added") + event.Update(NewSignal(event, "child_added")) return nil } diff --git a/graph.go b/graph.go index 66eca90..ff0c136 100644 --- a/graph.go +++ b/graph.go @@ -1,7 +1,6 @@ package main import ( - "errors" "log" "sync" "github.com/google/uuid" @@ -13,14 +12,47 @@ func randid() string{ return uuid_str } +type GraphSignal interface { + Source() GraphNode + Type() string + Description() string +} + +type BaseSignal struct { + source GraphNode + signal_type string + description string +} + +func (signal BaseSignal) Source() GraphNode { + return signal.source +} + +func (signal BaseSignal) Type() string { + return signal.signal_type +} + +func (signal BaseSignal) Description() string { + return signal.description +} + +func NewSignal(source GraphNode, signal_type string) (BaseSignal) { + signal := BaseSignal{ + source: source, + signal_type: signal_type, + } + return signal +} + // GraphNode is the interface common to both DAG nodes and Event tree nodes type GraphNode interface { Name() string Description() string ID() string - UpdateListeners(info string) error - UpdateChannel() chan string - Update(reason string) error + Update(update GraphSignal) error + RegisterChannel(listener chan GraphSignal) + UnregisterChannel(listener chan GraphSignal) + UpdateChannel() chan GraphSignal } // BaseNode is the most basic implementation of the GraphNode interface @@ -29,8 +61,9 @@ type BaseNode struct { name string description string id string - listeners []chan string + signal chan GraphSignal listeners_lock sync.Mutex + listeners map[chan GraphSignal]chan GraphSignal } func (node * BaseNode) Name() string { @@ -47,58 +80,47 @@ func (node * BaseNode) ID() string { // Create a new listener channel for the node, add it to the nodes listener list, and return the new channel const listener_buffer = 10 -func (node * BaseNode) UpdateChannel() chan string{ - new_listener := make(chan string, listener_buffer) - node.listeners_lock.Lock() - node.listeners = append(node.listeners, new_listener) - node.listeners_lock.Unlock() +func (node * BaseNode) UpdateChannel() chan GraphSignal { + new_listener := make(chan GraphSignal, listener_buffer) + node.RegisterChannel(new_listener) return new_listener } -// Send the update to listener channels -func (node * BaseNode) UpdateListeners(info string) error { - closed_listeners := []int{} - listeners_closed := false - - // Send each listener nil to signal it to check for new content - // if the first attempt to send it fails close the listener +func (node * BaseNode) RegisterChannel(listener chan GraphSignal) { node.listeners_lock.Lock() - for i, listener := range node.listeners { - select { - case listener <- info: - default: - close(listener) - closed_listeners = append(closed_listeners, i) - listeners_closed = true - } + _, exists := node.listeners[listener] + if exists == false { + node.listeners[listener] = listener } + node.listeners_lock.Unlock() +} - // If any listeners have been closed, loop over the listeners - // Add listeners to the "remaining" list if i insn't in closed_listeners - if listeners_closed == true { - remaining_listeners := []chan string{} - for i, listener := range node.listeners { - listener_closed := false - for _, index := range closed_listeners { - if index == i { - listener_closed = true - break - } - } - if listener_closed == false { - remaining_listeners = append(remaining_listeners, listener) - } - } - - node.listeners = remaining_listeners +func (node * BaseNode) UnregisterChannel(listener chan GraphSignal) { + node.listeners_lock.Lock() + _, exists := node.listeners[listener] + if exists == false { + panic("Attempting to unregister non-registered listener") + } else { + delete(node.listeners, listener) } node.listeners_lock.Unlock() +} - return nil +// Send the update to listener channels +func (node * BaseNode) UpdateListeners(update GraphSignal) { + node.listeners_lock.Lock() + + for _, listener := range node.listeners { + log.Printf("UPDATE_LISTENER %s: %p", node.Name(), listener) + listener <- update + } + + node.listeners_lock.Unlock() } -// Basic implementation must be overwritten to do anything useful -func (node * BaseNode) Update(reason string) error { - log.Printf("UPDATE: BaseNode %s: %s", node.Name(), reason) - return errors.New("Cannot Update a BaseNode") +// Basic implementation that sends the signal to the nodes channel +func (node * BaseNode) Update(signal GraphSignal) error { + log.Printf("UPDATE: BaseNode %s: %+v", node.Name(), signal) + node.UpdateListeners(signal) + return nil } diff --git a/main.go b/main.go index 7d65336..1b616b4 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "log" - "math/rand" ) func fake_team(org string, id string, names []string) (*Team, []*Member) { @@ -26,10 +25,14 @@ func fake_data() * EventManager { t6, m6 := fake_team("210", "X", []string{"toby"}) t7, m7 := fake_team("210", "Y", []string{"jennifer"}) t8, m8 := fake_team("210", "Z", []string{"emily"}) - t9, m9 := fake_team("315", "W", []string{"bobby"}) - t10, m10 := fake_team("315", "X", []string{"toby"}) - t11, m11 := fake_team("315", "Y", []string{"jennifer"}) - t12, m12 := fake_team("315", "Z", []string{"emily"}) + t9, m9 := fake_team("666", "A", []string{"jimmy"}) + t10, m10 := fake_team("666", "B", []string{"timmy"}) + //t11, m11 := fake_team("666", "C", []string{"grace"}) + //t12, m12 := fake_team("666", "D", []string{"jeremy"}) + //t13, m13 := fake_team("315", "W", []string{"bobby"}) + //t14, m14 := fake_team("315", "X", []string{"toby"}) + //t15, m15 := fake_team("315", "Y", []string{"jennifer"}) + //t16, m16 := fake_team("315", "Z", []string{"emily"}) teams = append(teams, t1) teams = append(teams, t2) @@ -41,8 +44,12 @@ func fake_data() * EventManager { teams = append(teams, t8) teams = append(teams, t9) teams = append(teams, t10) - teams = append(teams, t11) - teams = append(teams, t12) + //teams = append(teams, t11) + //teams = append(teams, t12) + //teams = append(teams, t13) + //teams = append(teams, t14) + //teams = append(teams, t15) + //teams = append(teams, t16) resources = append(resources, m1[0]) resources = append(resources, m2[0]) @@ -54,25 +61,22 @@ func fake_data() * EventManager { 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){ - for true { - idx := rand.Intn(len(teams)) - if idx != i { - alliance := NewAlliance(team, teams[idx]) - alliances = append(alliances, alliance) - break - } - } - } + //resources = append(resources, m11[0]) + //resources = append(resources, m12[0]) + //resources = append(resources, m13[0]) + //resources = append(resources, m14[0]) + //resources = append(resources, m15[0]) + //resources = append(resources, m16[0]) arenas := []*Arena{} arenas = append(arenas, NewVirtualArena("Arena 1")) arenas = append(arenas, NewVirtualArena("Arena 2")) arenas = append(arenas, NewVirtualArena("Arena 3")) + arenas = append(arenas, NewVirtualArena("Arena 4")) + arenas = append(arenas, NewVirtualArena("Arena 5")) + arenas = append(arenas, NewVirtualArena("Arena 6")) + arenas = append(arenas, NewVirtualArena("Arena 7")) + arenas = append(arenas, NewVirtualArena("Arena 8")) for _, arena := range arenas { resources = append(resources, arena) @@ -82,19 +86,27 @@ func fake_data() * EventManager { resources = append(resources, team) } + alliances := []*Alliance{} + for i, team := range(teams) { + for j, team2 := range(teams) { + if i != j { + alliance := NewAlliance(team, team2) + alliances = append(alliances, alliance) + } + } + } for _, alliance := range alliances { resources = append(resources, alliance) } + root_event := NewEventQueue("root_event", "", []Resource{}) event_manager := NewEventManager(root_event, resources) arena_idx := 0 - for i := 0; i < len(alliances)*5; i++ { - alliance := alliances[i % len(alliances)] - for true { - idx := rand.Intn(len(alliances)) - if idx != i { - alliance2 := alliances[idx] + // Generate 3 games for each team by picking 3 random teams + for i, alliance := range(alliances) { + for j, alliance2 := range(alliances) { + if j != i { if alliance.Children()[0] == alliance2.Children()[0] || alliance.Children()[0] == alliance2.Children()[1] || alliance.Children()[1] == alliance2.Children()[0] || alliance.Children()[1] == alliance2.Children()[1] { } else { match := NewMatch(alliance, alliance2, arenas[arena_idx]) @@ -108,7 +120,6 @@ func fake_data() * EventManager { arena_idx = 0 } } - break } } } diff --git a/manager.go b/manager.go index d636e14..3f0a3b8 100644 --- a/manager.go +++ b/manager.go @@ -55,8 +55,10 @@ func (manager * EventManager) Run() error { c <- nil } }(abort, aborts) + err := manager.root_event.LockResources() if err != nil { + abort <- nil return err } diff --git a/manager_test.go b/manager_test.go index 4ac3cae..36619f1 100644 --- a/manager_test.go +++ b/manager_test.go @@ -9,7 +9,7 @@ import ( type graph_tester testing.T const listner_timeout = 100 * time.Millisecond -func (t * graph_tester) CheckForValue(listener chan string, str string) { +func (t * graph_tester) CheckForValue(listener chan GraphSignal, str string) { timeout := time.After(listner_timeout) select { case <- listener: @@ -19,7 +19,7 @@ func (t * graph_tester) CheckForValue(listener chan string, str string) { } } -func (t * graph_tester) CheckForNone(listener chan string, str string) { +func (t * graph_tester) CheckForNone(listener chan GraphSignal, str string) { timeout := time.After(listner_timeout) select { case <- listener: @@ -99,21 +99,23 @@ func TestResourceUpdate(t * testing.T) { r4_l := r4.UpdateChannel() // Calling Update() on the parent with no other parents should only notify node listeners - r3.Update("test") + println("UPDATE_START") + r3.Update(NewSignal(nil, "test")) + println("UPDATE_DONE") (*graph_tester)(t).CheckForNone(r1_l, "Update on r1 after updating r3") (*graph_tester)(t).CheckForNone(r2_l, "Update on r2 after updating r3") (*graph_tester)(t).CheckForValue(r3_l, "No update on r3 after updating r3") (*graph_tester)(t).CheckForValue(r4_l, "No update on r4 after updating r3") // Calling Update() on a child should notify listeners of the parent and child, but not siblings - r2.Update("test") + r2.Update(NewSignal(nil, "test")) (*graph_tester)(t).CheckForNone(r1_l, "Update on r1 after updating r2") (*graph_tester)(t).CheckForValue(r2_l, "No update on r2 after updating r2") (*graph_tester)(t).CheckForValue(r3_l, "No update on r3 after updating r2") (*graph_tester)(t).CheckForValue(r4_l, "No update on r4 after updating r2") // Calling Update() on a child should notify listeners of the parent and child, but not siblings - r1.Update("test") + r1.Update(NewSignal(nil, "test")) (*graph_tester)(t).CheckForValue(r1_l, "No update on r1 after updating r1") (*graph_tester)(t).CheckForNone(r2_l, "Update on r2 after updating r1") (*graph_tester)(t).CheckForValue(r3_l, "No update on r3 after updating r1") @@ -268,7 +270,7 @@ func TestAddToEventQueue(t * testing.T) { } func TestStartBaseEvent(t * testing.T) { - event_1 := NewEvent("1", "", []Resource{}) + event_1 := NewEvent("TestStartBaseEvent event_1", "", []Resource{}) r := event_1.DoneResource() manager := NewEventManager(event_1, []Resource{}) @@ -331,7 +333,7 @@ func TestAbortEventQueue(t * testing.T) { } func TestStartEventQueue(t * testing.T) { - root_event := NewEventQueue("", "", []Resource{}) + root_event := NewEventQueue("root_event", "", []Resource{}) r := root_event.DoneResource() rel := root_event.UpdateChannel(); res_1 := NewResource("test_resource", "", []Resource{}) diff --git a/resource.go b/resource.go index 8c6b9a1..67014b2 100644 --- a/resource.go +++ b/resource.go @@ -9,15 +9,13 @@ import ( // Resources propagate update up to multiple parents, and not downwards // (subscriber to team won't get update to alliance, but subscriber to alliance will get update to team) -func (resource * BaseResource) Update(reason string) error { - log.Printf("UPDATE BaseResource %s: %s", resource.Name(), reason) - err := resource.UpdateListeners(reason) - if err != nil { - return err - } +func (resource * BaseResource) Update(signal GraphSignal) error { + log.Printf("UPDATE BaseResource %s: %+v", resource.Name(), signal) + + resource.BaseNode.Update(signal) for _, parent := range resource.Parents() { - err := parent.Update("update parents") + err := parent.Update(signal) if err != nil { return err } @@ -62,7 +60,7 @@ func (resource * BaseResource) Owner() Event { } func (resource * BaseResource) NotifyUnlocked() error { - err := resource.Update("finalize_unlock") + err := resource.Update(NewSignal(resource, "lock_change")) if err != nil { return err } @@ -78,7 +76,7 @@ func (resource * BaseResource) NotifyUnlocked() error { } func (resource * BaseResource) NotifyLocked() error { - err := resource.Update("finalize_lock") + err := resource.Update(NewSignal(resource, "lock_change")) if err != nil { return err } @@ -90,7 +88,7 @@ func (resource * BaseResource) NotifyLocked() error { } } - resource.lock_holder.Update("finalize_lock") + resource.lock_holder.Update(NewSignal(resource, "lock_change")) return nil } @@ -153,10 +151,6 @@ func (resource * BaseResource) Unlock(event Event) error { } resource.state_lock.Unlock() - /*if unlocked == true { - resource.Update("unlocking resource") - }*/ - return err } @@ -189,13 +183,13 @@ func (resource * BaseResource) AddParent(parent Resource) error { return nil } -func NewResource(name string, description string, children []Resource) * BaseResource { - resource := &BaseResource{ +func NewBaseResource(name string, description string, children []Resource) BaseResource { + resource := BaseResource{ BaseNode: BaseNode{ name: name, description: description, id: randid(), - listeners: []chan string{}, + listeners: map[chan GraphSignal]chan GraphSignal{}, }, parents: []Resource{}, children: children, @@ -203,3 +197,8 @@ func NewResource(name string, description string, children []Resource) * BaseRes return resource } + +func NewResource(name string, description string, children []Resource) * BaseResource { + resource := NewBaseResource(name, description, children) + return &resource +} diff --git a/vex.go b/vex.go index d00649c..08f2a92 100644 --- a/vex.go +++ b/vex.go @@ -13,16 +13,7 @@ type Member struct { func NewMember(name string) * Member { member := &Member{ - BaseResource: BaseResource{ - BaseNode: BaseNode{ - name: name, - description: "A Team Member", - id: randid(), - listeners: []chan string{}, - }, - parents: []Resource{}, - children: []Resource{}, - }, + BaseResource: NewBaseResource(name, "A Team Member", []Resource{}), } return member @@ -47,22 +38,15 @@ func NewTeam(org string, team string, members []*Member) * Team { name := fmt.Sprintf("%s%s", org, team) description := fmt.Sprintf("Team %s", name) resource := &Team{ - BaseResource: BaseResource{ - BaseNode: BaseNode{ - name: name, - description: description, - id: randid(), - listeners: []chan string{}, - }, - parents: []Resource{}, - children: make([]Resource, len(members)), - }, + BaseResource: NewBaseResource(name, description, make([]Resource, len(members))), Org: org, Team: team, } + for idx, member := range(members) { resource.children[idx] = member } + return resource } @@ -75,16 +59,7 @@ func NewAlliance(team0 * Team, team1 * Team) * Alliance { description := "" resource := &Alliance{ - BaseResource: BaseResource{ - BaseNode: BaseNode{ - name: name, - description: description, - id: randid(), - listeners: []chan string{}, - }, - parents: []Resource{}, - children: []Resource{team0, team1}, - }, + BaseResource: NewBaseResource(name, description, []Resource{team0, team1}), } return resource } @@ -103,16 +78,7 @@ type Arena struct { func NewVirtualArena(name string) * Arena { arena := &Arena{ - BaseResource: BaseResource{ - BaseNode: BaseNode{ - name: name, - description: "A virtual vex arena", - id: randid(), - listeners: []chan string{}, - }, - parents: []Resource{}, - children: []Resource{}, - }, + BaseResource: NewBaseResource(name, "A virtual vex arena", []Resource{}), connected: false, } @@ -128,28 +94,34 @@ func (arena * Arena) Lock(event Event) error { return arena.lock(event) } +func (arena * Arena) Update(signal GraphSignal) error { + log.Printf("UPDATE Arena %s: %+v", arena.Name(), signal) + + arena.BaseResource.Update(signal) + + if arena.connected == true { + arena.signal <- signal + } + + return nil +} + func (arena * Arena) Connect(abort chan error) bool { log.Printf("Connecting %s", arena.Name()) go func(arena * Arena, abort chan error) { - update_channel := arena.UpdateChannel() owner := arena.Owner() - var owner_channel chan string = nil - if owner != nil { - owner_channel = owner.UpdateChannel() - } arena.connected = true update_str := fmt.Sprintf("VIRTUAL_ARENA connected: %s", arena.Name()) - arena.Update(update_str) + signal := NewSignal(arena, "arena_connected") + signal.description = update_str + arena.Update(signal) log.Printf("VIRTUAL_ARENA goroutine starting: %s", arena.Name()) for true { select { case <- abort: log.Printf("Virtual arena %s aborting", arena.Name()) break - case update, ok := <- update_channel: - if !ok { - panic("own update_channel closed") - } + case update := <- arena.signal: log.Printf("%s update: %s", arena.Name(), update) new_owner := arena.Owner() if new_owner != owner { @@ -168,17 +140,9 @@ func (arena * Arena) Connect(abort chan error) bool { owner = new_owner if owner != nil { - owner_channel = owner.UpdateChannel() } else { - owner_channel = nil } } - case update, ok := <- owner_channel: - if !ok { - panic("owner update channel closed") - } - log.Printf("%s owner update: %s", arena.Name(), update) - log.Printf("owner: %s", owner.Name()) } } }(arena, abort) diff --git a/vex_test.go b/vex_test.go index 8362a1c..fdf3acf 100644 --- a/vex_test.go +++ b/vex_test.go @@ -130,9 +130,11 @@ func TestNewMatch(t *testing.T) { arena := NewVirtualArena(arena_name) - root_event := NewMatch(alliance_1, alliance_2, arena) + match := NewMatch(alliance_1, alliance_2, arena) + root_event := NewEventQueue("root_event", "", []Resource{}) 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.AddEvent(root_event, match, NewEventQueueInfo(1)) go func() { time.Sleep(time.Second * 2) @@ -140,7 +142,7 @@ func TestNewMatch(t *testing.T) { }() err := event_manager.Run() - if err == nil { + if err != nil { t.Fatal(err) } }