Beispiel #1
0
func profile(clk clock.Clock, w io.Writer, r io.Reader) (io.Writer, io.Reader, func() TimeProfile) {

	preciseWriter := &preciseTimedWriter{clk: clk, w: w}
	preciseReader := &preciseTimedReader{clk: clk, r: r}

	start := clk.Now()
	return preciseWriter, preciseReader, func() TimeProfile {
		return TimeProfile{
			Total:     clk.Now().Sub(start),
			WaitRead:  preciseReader.WaitRead(),
			WaitWrite: preciseWriter.WaitWrite(),
		}
	}
}
Beispiel #2
0
// NewBatch creates a new instance of Batch
func NewBatch(m *utils.Message, group string, deflate bool, done utils.Done,
	clk clock.Clock, timeoutMillis uint, ready chan *Batch) *Batch {
	var wg sync.WaitGroup

	payload, _ := m.PopPayload()
	b := &Batch{
		Group:        group,
		Deflate:      deflate,
		Done:         done,
		Message:      m,
		MessageCount: 1,
		Buf:          new(bytes.Buffer),
		Sent:         false,
	}

	if b.Deflate {
		b.Writer = zlib.NewWriter(b.Buf)
	} else {
		b.Writer = bufio.NewWriter(b.Buf)
	}

	b.Writer.Write(payload)

	if timeoutMillis > 0 {
		b.Timer = clk.Timer(time.Duration(timeoutMillis) * time.Millisecond)

		wg.Add(1)
		go func() {
			wg.Done()
			<-b.Timer.C
			if atomic.LoadUint64(&b.MessageCount) > 0 {
				ready <- b
			}
		}()
	}

	wg.Wait()
	return b
}
Beispiel #3
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
	}
}
Beispiel #4
0
// nowInMillis is a utility function that call Now on the clock and converts it
// to milliseconds.
func nowInMillis(c clock.Clock) int64 {
	return c.Now().UnixNano() / int64(time.Millisecond)
}
Beispiel #5
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)
}