Removed event.go
parent
a4115a4f99
commit
3d28c703db
@ -1,156 +0,0 @@
|
|||||||
package graphvent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type EventCommand string
|
|
||||||
type EventState string
|
|
||||||
|
|
||||||
type EventExt struct {
|
|
||||||
Name string `gv:"name"`
|
|
||||||
State EventState `gv:"state"`
|
|
||||||
StateStart time.Time `gv:"state_start"`
|
|
||||||
Parent NodeID `gv:"parent" node:"Base"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *EventExt) Load(ctx *Context, node *Node) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *EventExt) Unload(ctx *Context, node *Node) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEventExt(parent NodeID, name string) *EventExt {
|
|
||||||
return &EventExt{
|
|
||||||
Name: name,
|
|
||||||
State: "init",
|
|
||||||
Parent: parent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type EventStateSignal struct {
|
|
||||||
SignalHeader
|
|
||||||
Source NodeID `gv:"source"`
|
|
||||||
State EventState `gv:"state"`
|
|
||||||
Time time.Time `gv:"time"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (signal EventStateSignal) String() string {
|
|
||||||
return fmt.Sprintf("EventStateSignal(%s, %s, %s, %+v)", signal.SignalHeader, signal.Source, signal.State, signal.Time)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEventStateSignal(source NodeID, state EventState, t time.Time) *EventStateSignal {
|
|
||||||
return &EventStateSignal{
|
|
||||||
SignalHeader: NewSignalHeader(),
|
|
||||||
Source: source,
|
|
||||||
State: state,
|
|
||||||
Time: t,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type EventControlSignal struct {
|
|
||||||
SignalHeader
|
|
||||||
Command EventCommand `gv:"command"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (signal EventControlSignal) String() string {
|
|
||||||
return fmt.Sprintf("EventControlSignal(%s, %s)", signal.SignalHeader, signal.Command)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEventControlSignal(command EventCommand) *EventControlSignal {
|
|
||||||
return &EventControlSignal{
|
|
||||||
NewSignalHeader(),
|
|
||||||
command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *EventExt) UpdateState(node *Node, changes Changes, state EventState, state_start time.Time) {
|
|
||||||
if ext.State != state {
|
|
||||||
ext.StateStart = state_start
|
|
||||||
changes = append(changes, "state")
|
|
||||||
ext.State = state
|
|
||||||
node.QueueSignal(time.Now(), NewEventStateSignal(node.ID, ext.State, time.Now()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *EventExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) ([]SendMsg, Changes) {
|
|
||||||
var messages []SendMsg = nil
|
|
||||||
var changes = Changes{}
|
|
||||||
|
|
||||||
return messages, changes
|
|
||||||
}
|
|
||||||
|
|
||||||
type TestEventExt struct {
|
|
||||||
Length time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *TestEventExt) Load(ctx *Context, node *Node) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ext *TestEventExt) Unload(ctx *Context, node *Node) {
|
|
||||||
}
|
|
||||||
|
|
||||||
type EventCommandMap map[EventCommand]map[EventState]EventState
|
|
||||||
var test_event_commands = EventCommandMap{
|
|
||||||
"ready?": {
|
|
||||||
"init": "ready",
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"ready": "running",
|
|
||||||
},
|
|
||||||
"abort": {
|
|
||||||
"ready": "init",
|
|
||||||
},
|
|
||||||
"stop": {
|
|
||||||
"running": "stopped",
|
|
||||||
},
|
|
||||||
"finish": {
|
|
||||||
"running": "done",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (ext *TestEventExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) ([]SendMsg, Changes) {
|
|
||||||
var messages []SendMsg = nil
|
|
||||||
var changes = Changes{}
|
|
||||||
|
|
||||||
switch sig := signal.(type) {
|
|
||||||
case *EventControlSignal:
|
|
||||||
event_ext, err := GetExt[EventExt](node)
|
|
||||||
if err != nil {
|
|
||||||
messages = append(messages, SendMsg{source, NewErrorSignal(sig.Id, "not_event")})
|
|
||||||
} else {
|
|
||||||
ctx.Log.Logf("event", "%s got %s EventControlSignal while in %s", node.ID, sig.Command, event_ext.State)
|
|
||||||
new_state, error_signal := event_ext.ValidateEventCommand(sig, test_event_commands)
|
|
||||||
if error_signal != nil {
|
|
||||||
messages = append(messages, SendMsg{source, error_signal})
|
|
||||||
} else {
|
|
||||||
switch sig.Command {
|
|
||||||
case "start":
|
|
||||||
node.QueueSignal(time.Now().Add(ext.Length), NewEventControlSignal("finish"))
|
|
||||||
}
|
|
||||||
event_ext.UpdateState(node, changes, new_state, time.Now())
|
|
||||||
messages = append(messages, SendMsg{source, NewSuccessSignal(sig.Id)})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return messages, changes
|
|
||||||
}
|
|
||||||
|
|
||||||
func(ext *EventExt) ValidateEventCommand(signal *EventControlSignal, commands EventCommandMap) (EventState, *ErrorSignal) {
|
|
||||||
transitions, command_mapped := commands[signal.Command]
|
|
||||||
if command_mapped == false {
|
|
||||||
return "", NewErrorSignal(signal.Id, "unknown command %s", signal.Command)
|
|
||||||
} else {
|
|
||||||
new_state, valid_transition := transitions[ext.State]
|
|
||||||
if valid_transition == false {
|
|
||||||
return "", NewErrorSignal(signal.Id, "invalid command state %s(%s)", signal.Command, ext.State)
|
|
||||||
} else {
|
|
||||||
return new_state, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
package graphvent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
"crypto/rand"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEvent(t *testing.T) {
|
|
||||||
ctx := logTestContext(t, []string{"event", "listener", "listener_debug"})
|
|
||||||
err := RegisterExtension[TestEventExt](ctx, nil)
|
|
||||||
fatalErr(t, err)
|
|
||||||
err = RegisterObject[TestEventExt](ctx)
|
|
||||||
fatalErr(t, err)
|
|
||||||
|
|
||||||
|
|
||||||
event_public, event_private, err := ed25519.GenerateKey(rand.Reader)
|
|
||||||
event_listener := NewListenerExt(100)
|
|
||||||
event, err := NewNode(ctx, event_private, "Base", 100, NewEventExt(KeyID(event_public), "Test Event"), &TestEventExt{time.Second}, event_listener)
|
|
||||||
fatalErr(t, err)
|
|
||||||
|
|
||||||
response, signals := testSend(t, ctx, NewEventControlSignal("ready?"), event, event)
|
|
||||||
switch resp := response.(type) {
|
|
||||||
case *SuccessSignal:
|
|
||||||
case *ErrorSignal:
|
|
||||||
t.Fatalf("Error response %+v", resp.Error)
|
|
||||||
default:
|
|
||||||
t.Fatalf("Unexpected response %+v", resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
var state_signal *EventStateSignal = nil
|
|
||||||
for _, signal := range(signals) {
|
|
||||||
event_state, is_event_state := signal.(*EventStateSignal)
|
|
||||||
if is_event_state == true && event_state.Source == event.ID && event_state.State == "ready" {
|
|
||||||
state_signal = event_state
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if state_signal == nil {
|
|
||||||
state_signal, err = WaitForSignal(event_listener.Chan, 10*time.Millisecond, func(sig *EventStateSignal) bool {
|
|
||||||
return sig.Source == event.ID && sig.State == "ready"
|
|
||||||
})
|
|
||||||
fatalErr(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response, signals = testSend(t, ctx, NewEventControlSignal("start"), event, event)
|
|
||||||
switch resp := response.(type) {
|
|
||||||
case *SuccessSignal:
|
|
||||||
case *ErrorSignal:
|
|
||||||
t.Fatalf("Error response %+v", resp.Error)
|
|
||||||
default:
|
|
||||||
t.Fatalf("Unexpected response %+v", resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
state_signal = nil
|
|
||||||
for _, signal := range(signals) {
|
|
||||||
event_state, is_event_state := signal.(*EventStateSignal)
|
|
||||||
if is_event_state == true && event_state.Source == event.ID && event_state.State == "running" {
|
|
||||||
state_signal = event_state
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if state_signal == nil {
|
|
||||||
state_signal, err = WaitForSignal(event_listener.Chan, 10*time.Millisecond, func(sig *EventStateSignal) bool {
|
|
||||||
return sig.Source == event.ID && sig.State == "running"
|
|
||||||
})
|
|
||||||
fatalErr(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = WaitForSignal(event_listener.Chan, time.Second * 2, func(sig *EventStateSignal) bool {
|
|
||||||
return sig.Source == event.ID && sig.State == "done"
|
|
||||||
})
|
|
||||||
fatalErr(t, err)
|
|
||||||
|
|
||||||
response, signals = testSend(t, ctx, NewEventControlSignal("start"), event, event)
|
|
||||||
switch resp := response.(type) {
|
|
||||||
case *SuccessSignal:
|
|
||||||
t.Fatalf("Success response starting finished TestEventExt")
|
|
||||||
case *ErrorSignal:
|
|
||||||
default:
|
|
||||||
t.Fatalf("Unexpected response %+v", resp)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue