func (t *tracker) CLGIDs(CLG systemspec.CLG, networkPayload objectspec.NetworkPayload) error { destinationID := string(networkPayload.GetDestination()) sourceIDs := networkPayload.GetSources() errors := make(chan error, len(sourceIDs)) wg := sync.WaitGroup{} for _, s := range sourceIDs { wg.Add(1) go func(s string) { // Persist the single CLG ID connections. behaviourIDKey := key.NewNetworkKey("behaviour-id:%s:o:tracker:behaviour-ids", s) err := t.Storage().General().PushToSet(behaviourIDKey, destinationID) if err != nil { errors <- maskAny(err) } wg.Done() }(string(s)) } wg.Wait() select { case err := <-errors: if err != nil { return maskAny(err) } default: // Nothing do here. No error occurred. All good. } return nil }
func (f *forwarder) GetNetworkPayloads(CLG systemspec.CLG, networkPayload objectspec.NetworkPayload) ([]objectspec.NetworkPayload, error) { ctx := networkPayload.GetContext() // Check if there are behaviour IDs known that we can use to forward the // current network payload to. behaviourID, ok := ctx.GetBehaviourID() if !ok { return nil, maskAnyf(invalidBehaviourIDError, "must not be empty") } behaviourIDsKey := key.NewNetworkKey("forward:configuration:behaviour-id:%s:behaviour-ids", behaviourID) newBehaviourIDs, err := f.Storage().General().GetAllFromSet(behaviourIDsKey) if storage.IsNotFound(err) { // No configuration of behaviour IDs is stored. Thus we return an error. // Eventually some other lookup is able to find sufficient network payloads. return nil, maskAny(networkPayloadsNotFoundError) } else if err != nil { return nil, maskAny(err) } // Create a list of new network payloads. var newNetworkPayloads []objectspec.NetworkPayload for _, behaviourID := range newBehaviourIDs { // Prepare a new context for the new network payload. newCtx := ctx.Clone() newCtx.SetBehaviourID(behaviourID) // Create a new network payload. newNetworkPayloadConfig := networkpayload.DefaultConfig() newNetworkPayloadConfig.Args = networkPayload.GetArgs() newNetworkPayloadConfig.Context = newCtx newNetworkPayloadConfig.Destination = string(behaviourID) newNetworkPayloadConfig.Sources = []string{networkPayload.GetDestination()} newNetworkPayload, err := networkpayload.New(newNetworkPayloadConfig) if err != nil { return nil, maskAny(err) } newNetworkPayloads = append(newNetworkPayloads, newNetworkPayload) } return newNetworkPayloads, nil }
func (n *network) Calculate(CLG systemspec.CLG, networkPayload objectspec.NetworkPayload) (objectspec.NetworkPayload, error) { n.Log.WithTags(systemspec.Tags{C: nil, L: "D", O: n, V: 13}, "call Calculate") outputs, err := filterError(reflect.ValueOf(CLG.GetCalculate()).Call(networkPayload.GetCLGInput())) if err != nil { return nil, maskAny(err) } newNetworkPayloadConfig := networkpayload.DefaultConfig() newNetworkPayloadConfig.Args = outputs newNetworkPayloadConfig.Context = networkPayload.GetContext() newNetworkPayloadConfig.Destination = networkPayload.GetDestination() newNetworkPayloadConfig.Sources = networkPayload.GetSources() newNetworkPayload, err := networkpayload.New(newNetworkPayloadConfig) if err != nil { return nil, maskAny(err) } return newNetworkPayload, nil }
func (f *forwarder) News(CLG systemspec.CLG, networkPayload objectspec.NetworkPayload) ([]objectspec.NetworkPayload, error) { ctx := networkPayload.GetContext() // Decide how many new behaviour IDs should be created. This defines the // number of signals being forwarded to other CLGs. Here we want to make a // pseudo random decision. CreateMax takes a max paramater which is exclusive. // Therefore we increment the configuration for the maximum signals desired by // one, to reflect the maximum setting properly. maxSignals, err := f.Service().Random().CreateMax(f.GetMaxSignals() + 1) if err != nil { return nil, maskAny(err) } // Create the desired number of behaviour IDs. var newBehaviourIDs []string for i := 0; i < maxSignals; i++ { newBehaviourID, err := f.Service().ID().New() if err != nil { return nil, maskAny(err) } newBehaviourIDs = append(newBehaviourIDs, string(newBehaviourID)) } // TODO find a CLG name that can be connected to the current CLG for each new // behaviour ID and pair these combinations (network event tracker) // Store each new behaviour ID in the underlying storage. behaviourID, ok := ctx.GetBehaviourID() if !ok { return nil, maskAnyf(invalidBehaviourIDError, "must not be empty") } behaviourIDsKey := key.NewNetworkKey("forward:configuration:behaviour-id:%s:behaviour-ids", behaviourID) for _, behaviourID := range newBehaviourIDs { // TODO store asynchronuously err = f.Storage().General().PushToSet(behaviourIDsKey, behaviourID) if err != nil { return nil, maskAny(err) } } // Create a list of new network payloads. var newNetworkPayloads []objectspec.NetworkPayload for _, behaviourID := range newBehaviourIDs { // Prepare a new context for the new network payload. newCtx := ctx.Clone() newCtx.SetBehaviourID(behaviourID) // TODO set the paired CLG name to the new context // Create a new network payload. newNetworkPayloadConfig := networkpayload.DefaultConfig() newNetworkPayloadConfig.Args = networkPayload.GetArgs() newNetworkPayloadConfig.Context = newCtx newNetworkPayloadConfig.Destination = string(behaviourID) newNetworkPayloadConfig.Sources = []string{networkPayload.GetDestination()} newNetworkPayload, err := networkpayload.New(newNetworkPayloadConfig) if err != nil { return nil, maskAny(err) } newNetworkPayloads = append(newNetworkPayloads, newNetworkPayload) } return newNetworkPayloads, nil }