func (t *Throttler) SetProcess(process jaeger.Process) {
	if process.UUID != "" {
		t.uuid.Store(process.UUID)
	}
}
SetProcess implements ProcessSetter#SetProcess. It's imperative that the UUID is set before any remote
requests are made.
package remote
import (
	"fmt"
	"net/url"
	"sync"
	"sync/atomic"
	"time"
	"github.com/pkg/errors"
	"github.com/uber/jaeger-client-go"
	"github.com/uber/jaeger-client-go/utils"
)
const (
	minimumCredits = 1.0
)
var (
	errorUUIDNotSet = errors.New("Throttler UUID must be set")
)
type operationBalance struct {
	Operation string  `json:"operation"`
	Balance   float64 `json:"balance"`
}
type creditResponse struct {
	Balances []operationBalance `json:"balances"`
}
type httpCreditManagerProxy struct {
	hostPort string
}
func newHTTPCreditManagerProxy(hostPort string) *httpCreditManagerProxy {
	return &httpCreditManagerProxy{
		hostPort: hostPort,
	}
}
func (m *httpCreditManagerProxy) FetchCredits(uuid, serviceName string, operations []string) (*creditResponse, error) {
	params := url.Values{}
	params.Set("service", serviceName)
	params.Set("uuid", uuid)
	for _, op := range operations {
		params.Add("operations", op)
	}
	var resp creditResponse
	if err := utils.GetJSON(fmt.Sprintf("http://%s/credits?%s", m.hostPort, params.Encode()), &resp); err != nil {
		return nil, errors.Wrap(err, "Failed to receive credits from agent")
	}
	return &resp, nil
}
type Throttler struct {
	options
	mux           sync.RWMutex
	service       string
	uuid          atomic.Value
	creditManager *httpCreditManagerProxy
	credits       map[string]float64  
	close         chan struct{}
	stopped       sync.WaitGroup
}
func NewThrottler(service string, options ...Option) *Throttler {
	opts := applyOptions(options...)
	creditManager := newHTTPCreditManagerProxy(opts.hostPort)
	t := &Throttler{
		options:       opts,
		creditManager: creditManager,
		service:       service,
		credits:       make(map[string]float64),
		close:         make(chan struct{}),
	}
	t.stopped.Add(1)
	go t.pollManager()
	return t
}
func (t *Throttler) IsAllowed(operation string) bool {
	t.mux.Lock()
	defer t.mux.Unlock()
	value, ok := t.credits[operation]
	if !ok || value == 0 {
		if !ok {
			t.credits[operation] = 0
		}
		if !t.synchronousInitialization {
			t.metrics.ThrottledDebugSpans.Inc(1)
			return false
		}
		credits, err := t.fetchCredits([]string{operation})
		if err != nil {
			t.logger.Error("Failed to fetch credits: " + err.Error())
			return false
		}
		if len(credits.Balances) == 0 {
			return false
		}
		for _, opBalance := range credits.Balances {
			t.credits[opBalance.Operation] += opBalance.Balance
		}
	}
	return t.isAllowed(operation)
}
func (t *Throttler) Close() error {
	close(t.close)
	t.stopped.Wait()
	return nil
}