func()

in pkg/client/client_v2.go [976:1060]


func (c *clientV2) tryPerformDiagnostics(actionResults chan *proto.ActionResponse, action *proto.ActionRequest) {
	// see if we can unpack params
	foundParams := map[string]bool{}
	if len(action.GetParams()) > 0 {
		params := DiagnosticParams{}
		err := json.Unmarshal(action.GetParams(), &params)
		if err != nil {
			actionResults <- &proto.ActionResponse{
				Token:  c.token,
				Id:     action.GetId(),
				Status: proto.ActionResponse_FAILED,
				Result: []byte(fmt.Sprintf("error unmarshaling json in params: %s", err)),
			}
		}
		// convert to a map for easier checking
		for _, param := range params.AdditionalMetrics {
			foundParams[param] = true
		}
	}

	// break apart the action:
	// if it's unit-level, fetch unit-level diagnostics.
	// if component-level, just run diagnostics that are registered at the client level.
	diagHooks := make(map[string]diagHook)
	if action.GetLevel() == proto.ActionRequest_COMPONENT || action.GetLevel() == proto.ActionRequest_ALL {
		c.dmx.RLock()
		for n, d := range c.diagHooks {
			diagHooks[n] = d
		}
		c.dmx.RUnlock()

	}

	if action.GetLevel() == proto.ActionRequest_UNIT || action.GetLevel() == proto.ActionRequest_ALL {
		// find the unit
		c.unitsMu.RLock()
		unit := c.findUnit(action.GetUnitId(), UnitType(action.GetUnitType()))
		c.unitsMu.RUnlock()
		if unit == nil {
			actionResults <- &proto.ActionResponse{
				Token:  c.token,
				Id:     action.GetId(),
				Status: proto.ActionResponse_FAILED,
				Result: ActionErrUnitNotFound,
			}
			return
		}

		// gather diagnostics hooks for this unit
		unit.dmx.RLock()
		for n, d := range unit.diagHooks {
			diagHooks[n] = d
		}
		unit.dmx.RUnlock()
	}

	// perform diagnostics in goroutine, so we don't block other work
	go func() {
		res := make([]*proto.ActionDiagnosticUnitResult, 0, len(diagHooks))
		for diagName, diagHook := range diagHooks {
			// if the hook came with a tag, check it.
			// if the callback was registered with a tag but none was found in the request, skip it
			if diagHook.optionalWithParamTag != "" {
				if _, ok := foundParams[diagHook.optionalWithParamTag]; !ok {
					continue
				}
			}
			content := diagHook.hook()
			res = append(res, &proto.ActionDiagnosticUnitResult{
				Name:        diagName,
				Filename:    diagHook.filename,
				Description: diagHook.description,
				ContentType: diagHook.contentType,
				Content:     content,
				Generated:   timestamppb.New(time.Now().UTC()),
			})
		}
		actionResults <- &proto.ActionResponse{
			Token:      c.token,
			Id:         action.GetId(),
			Status:     proto.ActionResponse_SUCCESS,
			Diagnostic: res,
		}
	}()
}