grlx
grlx copied to clipboard
convert this to a request and get back the list of targeted sprouts
jw, err := json.Marshal(result)
if err != nil {
color.Red("%s: \n returned an invalid message!\n", keyID)
continue
}
var value types.CmdRun
err = json.NewDecoder(bytes.NewBuffer(jw)).Decode(&value)
if err != nil {
color.Red("%s returned an invalid message!\n", keyID)
continue
}
if value.ErrCode != 0 {
color.Red("%s:\n", keyID)
} else {
fmt.Printf("%s:\n", keyID)
}
if noerr {
fmt.Printf("%s\n", value.Stdout)
} else {
fmt.Printf("%s%s\n", value.Stdout, value.Stderr)
}
}
https://api.github.com/gogrlx/grlx/blob/b62aac111daf79788bc26221822bfdfc7081ed02/cmd/grlx/cmd/cook.go#L115
if err != nil {
log.Fatal(err)
}
finished := make(chan struct{}, 1)
completions := make(chan types.SproutStepCompletion)
topic := fmt.Sprintf("grlx.cook.*.%s", jid)
completionSteps := make(map[string][]types.StepCompletion)
sub, err := ec.Subscribe(topic, func(msg *nats.Msg) {
var step types.StepCompletion
err := json.Unmarshal(msg.Data, &step)
if err != nil {
log.Errorf("Error unmarshalling message: %v\n", err)
return
}
subComponents := strings.Split(msg.Subject, ".")
sproutID := subComponents[2]
completions <- types.SproutStepCompletion{SproutID: sproutID, CompletedStep: step}
if string(step.ID) == fmt.Sprintf("completed-%s", jid) {
return
} else if string(step.ID) == fmt.Sprintf("start-%s", jid) {
return
}
switch outputMode {
case "json":
case "":
fallthrough
case "text":
var b strings.Builder
b.WriteString(fmt.Sprintf("%s::%s\n", sproutID, jid))
b.WriteString(fmt.Sprintf("ID: %s\n", step.ID))
switch step.CompletionStatus {
case types.StepCompleted:
b.WriteString(color.GreenString(fmt.Sprintf("\tResult: %s\n", "Success")))
case types.StepFailed:
b.WriteString(color.RedString(fmt.Sprintf("\tResult: %s\n", "Failure")))
default:
// TODO add a status for skipped steps
b.WriteString(color.YellowString(fmt.Sprintf("\tResult: %s\n", "Unknown")))
}
b.WriteString("\tExecution Notes: \n")
for _, change := range step.Changes {
b.WriteString(fmt.Sprintf("\t\t%s\n", change))
}
// TODO add started and duration
b.WriteString("----------\n")
printTex.Lock()
fmt.Print(b.String())
printTex.Unlock()
}
})
if err != nil {
log.Printf("Error subscribing to %s: %v\n", topic, err)
log.Fatal(err)
}
// TODO convert this to a request and get back the list of targeted sprouts
ec.Publish(fmt.Sprintf("grlx.farmer.cook.trigger.%s", jid), types.TriggerMsg{JID: jid})
timeout := time.After(30 * time.Second)
dripTimeout := time.After(120 * time.Second)
concurrent := 0
defer sub.Unsubscribe()
defer nc.Flush()
waitLoop:
for {
select {
case completion := <-completions:
if string(completion.CompletedStep.ID) == fmt.Sprintf("start-%s", jid) {
concurrent++
}
if string(completion.CompletedStep.ID) == fmt.Sprintf("completed-%s", jid) {
// waitgroups are not necesary here because we are looping sequentially over a channel
concurrent--
}
if concurrent == 0 {
dripTimeout = time.After(time.Second / 10)
}
completionSteps[completion.SproutID] = append(completionSteps[completion.SproutID], completion.CompletedStep)
timeout = time.After(30 * time.Second)
case <-finished:
break waitLoop
case <-dripTimeout:
finished <- struct{}{}
break waitLoop
case <-timeout:
color.Red("Cooking timed out after 30 seconds.")
finished <- struct{}{}
break waitLoop
}
}
switch outputMode {
case "json":
wrapper := map[string]interface{}{}
wrapper["jid"] = jid
wrapper["sprouts"] = completionSteps
jsonBytes, err := json.Marshal(wrapper)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonBytes))
case "":
fallthrough
case "text":
for k, v := range completionSteps {
successes := -2 // -2 because we don't count the start and completed steps
failures := 0
errors := []string{}
for _, step := range v {
if step.CompletionStatus == types.StepCompleted {
successes++
} else if step.CompletionStatus == types.StepFailed {
failures++
}
if step.Error != nil {
errors = append(errors, step.Error.Error())
}
}
fmt.Printf("Summary for %s, JID %s:\n", k, jid)
fmt.Printf("\tSuccesses:\t%d\n", successes)
fmt.Printf("\tFailures:\t%d\n", failures)
fmt.Printf("\tErrors:\t\t%d\n", len(errors))
for _, err := range errors {
fmt.Printf("\t\t%s\n", err)
}
}
}
},
}