func()

in strategy/sampling/centralized.go [347:438]


func (ss *CentralizedStrategy) refreshTargets() (err error) {
	// Explicitly recover from panics since this is the entry point for a long-running goroutine
	// and we can not allow a panic to propagate to customer code.
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("%v", r)
		}
	}()

	// Flag indicating batch failure
	failed := false

	// Flag indicating whether or not manifest should be refreshed
	refresh := false

	// Generate sampling statistics
	statistics := ss.snapshots()

	// Do not refresh targets if no statistics to report
	if len(statistics) == 0 {
		logger.Debugf("No statistics to report. Not refreshing sampling targets.")
		return nil
	}

	// Get sampling targets
	output, err := ss.proxy.GetSamplingTargets(statistics)
	if err != nil {
		return
	}

	// Update sampling targets
	for _, t := range output.SamplingTargetDocuments {
		if err = ss.updateTarget(t); err != nil {
			failed = true
			logger.Debugf("Error occurred updating target for rule. %v", err)
		}
	}

	// Consume unprocessed statistics messages
	for _, s := range output.UnprocessedStatistics {
		logger.Debugf(
			"Error occurred updating sampling target for rule: %s, code: %s, message: %s",
			s.RuleName,
			s.ErrorCode,
			s.Message,
		)

		// Do not set any flags if error is unknown
		if s.ErrorCode == nil || s.RuleName == nil {
			continue
		}

		// Set batch failure if any sampling statistics return 5xx
		if strings.HasPrefix(*s.ErrorCode, "5") {
			failed = true
		}

		// Set refresh flag if any sampling statistics return 4xx
		if strings.HasPrefix(*s.ErrorCode, "4") {
			refresh = true
		}
	}

	// Set err if updates failed
	if failed {
		err = errors.New("error occurred updating sampling targets")
	} else {
		logger.Debug("Successfully refreshed sampling targets")
	}

	// Set refresh flag if modifiedAt timestamp from remote is greater than ours.
	if remote := output.LastRuleModification; remote != nil {
		ss.manifest.mu.RLock()
		local := ss.manifest.refreshedAt
		ss.manifest.mu.RUnlock()

		if *remote >= float64(local) {
			refresh = true
		}
	}
	// Perform out-of-band async manifest refresh if flag is set
	if refresh {
		logger.Infof("Refreshing sampling rules out-of-band.")

		go func() {
			if err := ss.refreshManifest(); err != nil {
				logger.Debugf("Error occurred refreshing sampling rules out-of-band. %v", err)
			}
		}()
	}
	return
}