diff --git a/context.go b/context.go index d2131f9..91d0118 100644 --- a/context.go +++ b/context.go @@ -435,7 +435,12 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) { return nil, err } - err = ctx.RegisterType(reflect.TypeOf(EventCommand("")), EventCommandType, nil, nil, nil, DeserializeString[EventState]) + err = ctx.RegisterType(reflect.TypeOf(WaitReason("")), WaitReasonType, nil, nil, nil, DeserializeString[WaitReason]) + if err != nil { + return nil, err + } + + err = ctx.RegisterType(reflect.TypeOf(EventCommand("")), EventCommandType, nil, nil, nil, DeserializeString[EventCommand]) if err != nil { return nil, err } diff --git a/gql.go b/gql.go index ba6f004..d271890 100644 --- a/gql.go +++ b/gql.go @@ -1183,6 +1183,14 @@ func NewGQLExtContext() *GQLExtContext { }, } type_map := map[reflect.Type]GQLTypeInfo{ + reflect.TypeOf(EventCommand("")): { + func (ctx *GQLExtContext, reflect_type reflect.Type)(graphql.Type, error) { + return graphql.String, nil + }, + func(ctx *GQLExtContext, value interface{})(reflect.Value, error) { + return reflect.ValueOf(EventCommand(value.(string))), nil + }, + }, reflect.TypeOf([2]NodeID{}): { func(ctx *GQLExtContext, reflect_type reflect.Type)(graphql.Type, error) { return graphql.NewList(graphql.String), nil diff --git a/gql_signal.go b/gql_signal.go index 4a9fda2..4c5899b 100644 --- a/gql_signal.go +++ b/gql_signal.go @@ -37,6 +37,7 @@ type StructFieldInfo struct { } func SignalFromArgs(ctx *GQLExtContext, signal_type reflect.Type, fields []StructFieldInfo, args map[string]interface{}, id_index, direction_index []int) (Signal, error) { + fmt.Printf("FIELD: %+v\n", fields) signal_value := reflect.New(signal_type) id_field := signal_value.Elem().FieldByIndex(id_index) @@ -58,6 +59,7 @@ func SignalFromArgs(ctx *GQLExtContext, signal_type reflect.Type, fields []Struc if err != nil { return nil, err } + fmt.Printf("Setting %s to %+v of type %+v\n", field.Name, value, value.Type()) field_value.Set(value) } return signal_value.Interface().(Signal), nil diff --git a/lockable.go b/lockable.go index cc62618..5957999 100644 --- a/lockable.go +++ b/lockable.go @@ -5,6 +5,12 @@ import ( "time" ) +var AllowParentUnlockPolicy = NewOwnerOfPolicy(Tree{ + SerializedType(LockSignalType): { + Hash(LockStateBase, "unlock"): nil, + }, +}) + var AllowAnyLockPolicy = NewAllNodesPolicy(Tree{ SerializedType(LockSignalType): { Hash(LockStateBase, "lock"): nil, @@ -111,6 +117,17 @@ func (ext *LockableExt) HandleErrorSignal(ctx *Context, node *Node, source NodeI } } case Unlocking: + ext.Requirements[info.Destination] = Locked + all_returned := true + for _, state := range(ext.Requirements) { + if state == Unlocking { + all_returned = false + break + } + } + if all_returned == true { + ext.State = Locked + } } } else { ctx.Log.Logf("lockable", "Got mapped error %s, but %s isn't a requirement", signal, info.Destination) @@ -352,6 +369,17 @@ func (ext *LockableExt) HandleTimeoutSignal(ctx *Context, node *Node, source Nod } } case Unlocking: + ext.Requirements[wait_info.Destination] = Locked + all_returned := true + for _, state := range(ext.Requirements) { + if state == Unlocking { + all_returned = false + break + } + } + if all_returned == true { + ext.State = Locked + } } } else { ctx.Log.Logf("lockable", "%s timed out", wait_info.Destination) diff --git a/node.go b/node.go index 8f3f61d..40f558b 100644 --- a/node.go +++ b/node.go @@ -154,10 +154,11 @@ func (node *Node) Allows(ctx *Context, principal_id NodeID, action Tree)(map[uui return nil, Deny } +type WaitReason string type WaitInfo struct { Destination NodeID `gv:"destination"` Timeout uuid.UUID `gv:"timeout"` - Reason string `gv:"reason"` + Reason WaitReason `gv:"reason"` } type WaitMap map[uuid.UUID]WaitInfo @@ -176,7 +177,7 @@ func (node *Node) ProcessResponse(wait_map WaitMap, response ResponseSignal) (Wa return WaitInfo{}, false } -func (node *Node) NewTimeout(reason string, dest NodeID, timeout time.Duration) (WaitInfo, uuid.UUID) { +func (node *Node) NewTimeout(reason WaitReason, dest NodeID, timeout time.Duration) (WaitInfo, uuid.UUID) { id := uuid.New() timeout_signal := NewTimeoutSignal(id) @@ -190,7 +191,7 @@ func (node *Node) NewTimeout(reason string, dest NodeID, timeout time.Duration) } // Creates a timeout signal for signal, queues it for the node at the timeout, and returns the WaitInfo -func (node *Node) QueueTimeout(reason string, dest NodeID, signal Signal, timeout time.Duration) WaitInfo { +func (node *Node) QueueTimeout(reason WaitReason, dest NodeID, signal Signal, timeout time.Duration) WaitInfo { timeout_signal := NewTimeoutSignal(signal.ID()) node.QueueSignal(time.Now().Add(timeout), timeout_signal) diff --git a/serialize.go b/serialize.go index 5a0f422..05c0624 100644 --- a/serialize.go +++ b/serialize.go @@ -268,6 +268,7 @@ var ( MapType = NewSerializedType("MAP") EventStateType = NewSerializedType("EVENT_STATE") + WaitReasonType = NewSerializedType("WAIT_REASON") EventCommandType = NewSerializedType("EVENT_COMMAND") ReqStateType = NewSerializedType("REQ_STATE") WaitInfoType = NewSerializedType("WAIT_INFO")