Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert this to a request and get back the list of targeted sprouts #89

Open
github-actions bot opened this issue Nov 5, 2023 · 0 comments
Open
Assignees
Labels

Comments

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2023

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)
				}
			}
		}
	},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant