func (sp SinePacer) Pace(elapsedTime time.Duration, elapsedHits uint64) (time.Duration, bool) {
	if sp.invalid() {
		return 0, true
	}
	expectedHits := sp.hits(elapsedTime)
	if elapsedHits < uint64(expectedHits) {
		return 0, false
	}
	nsPerHit := math.Round(1 / sp.hitsPerNs(elapsedTime))
	hitsToWait := float64(elapsedHits+1) - expectedHits
	nextHitIn := time.Duration(nsPerHit * hitsToWait)
	for i := 0; i < 5; i++ {
		hitsAtGuess := sp.hits(elapsedTime + nextHitIn)
		err := float64(elapsedHits+1) - hitsAtGuess
		if math.Abs(err) < 1e-3 {
			return nextHitIn, false
		}
		nextHitIn = time.Duration(float64(nextHitIn) / (hitsAtGuess - float64(elapsedHits)))
	}
	return nextHitIn, false
}
Pace determines the length of time to sleep until the next hit is sent.
package vegeta
import (
	"fmt"
	"math"
	"time"
)
type Pacer interface {
	Pace(elapsed time.Duration, hits uint64) (wait time.Duration, stop bool)
	Rate(elapsed time.Duration) float64
}
type PacerFunc func(time.Duration, uint64) (time.Duration, bool)
func (pf PacerFunc) Pace(elapsed time.Duration, hits uint64) (time.Duration, bool) {
	return pf(elapsed, hits)
}
type ConstantPacer struct {
	Freq int            
	Per  time.Duration  
}
type Rate = ConstantPacer
var _ Pacer = ConstantPacer{}
func (cp ConstantPacer) String() string {
	return fmt.Sprintf("Constant{%d hits/%s}", cp.Freq, cp.Per)
}
func (cp ConstantPacer) Pace(elapsed time.Duration, hits uint64) (time.Duration, bool) {
	switch {
	case cp.Per == 0 || cp.Freq == 0:
		return 0, false  
	case cp.Per < 0 || cp.Freq < 0:
		return 0, true
	}
	expectedHits := uint64(cp.Freq) * uint64(elapsed/cp.Per)
	if hits < expectedHits {
		return 0, false
	}
	interval := uint64(cp.Per.Nanoseconds() / int64(cp.Freq))
	if math.MaxInt64/interval < hits {
		return 0, true
	}
	delta := time.Duration((hits + 1) * interval)
	return delta - elapsed, false
}
func (cp ConstantPacer) Rate(elapsed time.Duration) float64 {
	return cp.hitsPerNs() * 1e9
}
func (cp ConstantPacer) hitsPerNs() float64 {
	return float64(cp.Freq) / float64(cp.Per)
}
const (
	MeanUp float64 = 0
	Peak = math.Pi / 2
	MeanDown = math.Pi
	Trough = 3 * math.Pi / 2
)
type SinePacer struct {
	Period time.Duration
	Mean Rate
	Amp Rate
	StartAt float64
}
var _ Pacer = SinePacer{}
func (sp SinePacer) String() string {
	return fmt.Sprintf("Sine{%s ± %s / %s, offset %g𝛑}", sp.Mean, sp.Amp, sp.Period, sp.StartAt/math.Pi)
}
func (sp SinePacer) invalid() bool {
	return sp.Period <= 0 || sp.Mean.hitsPerNs() <= 0 || sp.Amp.hitsPerNs() >= sp.Mean.hitsPerNs()
}