Пример #1
0
func profileSample(clk clock.Clock, w io.Writer, r io.Reader, res time.Duration) (io.Writer, io.Reader, func() SamplingProfile) {
	samplingWriter := &samplingTimeWriter{w: w}
	samplingReader := &samplingTimeReader{r: r}

	start := clk.Now()
	done := make(chan struct{})

	samples := SamplingProfile{}
	go func() {
		ticker := clk.Ticker(res)
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:

				isWriting := atomic.LoadUint32(&samplingWriter.state) == stateBlocked
				isReading := atomic.LoadUint32(&samplingReader.state) == stateBlocked

				if isWriting {
					samples.Writing++
				} else {
					samples.NotWriting++
				}
				if isReading {
					samples.Reading++
				} else {
					samples.NotReading++
				}
			case <-done:
				return
			}
		}
	}()

	return samplingWriter, samplingReader, func() SamplingProfile {
		close(done)
		total := clk.Now().Sub(start)
		samples.TimeProfile = TimeProfile{
			Total:     total,
			WaitRead:  time.Duration(float64(samples.Reading) / float64(samples.Reading+samples.NotReading) * float64(total)),
			WaitWrite: time.Duration(float64(samples.Writing) / float64(samples.Writing+samples.NotWriting) * float64(total)),
		}
		return samples
	}
}
Пример #2
0
// GetAlignedTicker returns a ticker so that, let's say interval is a second
// then it will tick at every whole second, or if it's 60s than it's every whole
// minute. Note that in my testing this is about .0001 to 0.0002 seconds off due
// to scheduling etc.
func GetAlignedTicker(c clock.Clock, period time.Duration) *clock.Ticker {
	unix := c.Now().UnixNano()
	diff := time.Duration(period - (time.Duration(unix) % period))
	return c.Ticker(diff)
}