// Tick is used to perform a single round of failure detection and gossip
352794
func (m *Memberlist) probe() {
	// Track the number of indexes we've considered probing
	numCheck := 0
START:
	m.nodeLock.RLock()

	// Make sure we don't wrap around infinitely
	if numCheck >= len(m.nodes) {
		m.nodeLock.RUnlock()
		return
	}

	// Handle the wrap around case
	if m.probeIndex >= len(m.nodes) {
		m.nodeLock.RUnlock()
		m.resetNodes()
		m.probeIndex = 0
		numCheck++
		goto START
	}

	// Determine if we should probe this node
	skip := false
	var node nodeState

	node = *m.nodes[m.probeIndex]
	if node.Name == m.config.Name {
		skip = true
	} else if node.State == stateDead {
		skip = true
	}

	// Potentially skip
	m.nodeLock.RUnlock()
	m.probeIndex++
	if skip {
		numCheck++
		goto START
	}

	// Probe the specific node
	m.probeNode(&node)
}
1224302
func (conn *Conn) ping() {
	defer conn.wg.Done()
	tick := time.NewTicker(conn.cfg.PingFreq)
	for {
		select {
		case <-tick.C:
			conn.Ping(fmt.Sprintf("%d", time.Now().UnixNano()))
		case <-conn.die:
			// control channel closed, bail out
			tick.Stop()
			return
		}
	}
}
1197873
func (p *Peer) pingHandler() {
	pingTicker := time.NewTicker(pingInterval)
	defer pingTicker.Stop()

out:
	for {
		select {
		case <-pingTicker.C:
			nonce, err := wire.RandomUint64()
			if err != nil {
				log.Errorf("Not sending ping to %s: %v", p, err)
				continue
			}
			p.QueueMessage(wire.NewMsgPing(nonce), nil)

		case <-p.quit:
			break out
		}
	}
}
1168583
func (ft *fakeTicker) tick() {
	tick := ft.clock.Now()
	for {
		tick = tick.Add(ft.period)
		remaining := tick.Sub(ft.clock.Now())
		if remaining <= 0 {
			// The tick should have already happened. This can happen when
			// Advance() is called on the fake clock with a duration larger
			// than this ticker's period.
			select {
			case ft.c <- tick:
			default:
			}
			continue
		}

		select {
		case <-ft.stop:
			return
		case <-ft.clock.After(remaining):
			select {
			case ft.c <- tick:
			default:
			}
		}
	}
}
172369
func (l *WAL) sync() {
	err := l.currentSegmentWriter.sync()
	for len(l.syncWaiters) > 0 {
		errC := <-l.syncWaiters
		errC <- err
	}
}
392977
func (cw *CloudWatch) Send() error {
	cw.mtx.RLock()
	defer cw.mtx.RUnlock()
	now := time.Now()

	var datums []*cloudwatch.MetricDatum

	cw.counters.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
		value := sum(values)
		datums = append(datums, &cloudwatch.MetricDatum{
			MetricName: aws.String(name),
			Dimensions: makeDimensions(lvs...),
			Value:      aws.Float64(value),
			Timestamp:  aws.Time(now),
		})
		return true
	})

	cw.gauges.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
		value := last(values)
		datums = append(datums, &cloudwatch.MetricDatum{
			MetricName: aws.String(name),
			Dimensions: makeDimensions(lvs...),
			Value:      aws.Float64(value),
			Timestamp:  aws.Time(now),
		})
		return true
	})

	// format a [0,1]-float value to a percentile value, with minimum nr of decimals
	// 0.90 -> "90"
	// 0.95 -> "95"
	// 0.999 -> "99.9"
	formatPerc := func(p float64) string {
		return strconv.FormatFloat(p*100, 'f', -1, 64)
	}

	cw.histograms.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
		histogram := generic.NewHistogram(name, 50)

		for _, v := range values {
			histogram.Observe(v)
		}

		for _, perc := range cw.percentiles {
			value := histogram.Quantile(perc)
			datums = append(datums, &cloudwatch.MetricDatum{
				MetricName: aws.String(fmt.Sprintf("%s_%s", name, formatPerc(perc))),
				Dimensions: makeDimensions(lvs...),
				Value:      aws.Float64(value),
				Timestamp:  aws.Time(now),
			})
		}
		return true
	})

	var batches [][]*cloudwatch.MetricDatum
	for len(datums) > 0 {
		var batch []*cloudwatch.MetricDatum
		lim := min(len(datums), maxConcurrentRequests)
		batch, datums = datums[:lim], datums[lim:]
		batches = append(batches, batch)
	}

	var errors = make(chan error, len(batches))
	for _, batch := range batches {
		go func(batch []*cloudwatch.MetricDatum) {
			cw.sem <- struct{}{}
			defer func() {
				<-cw.sem
			}()
			_, err := cw.svc.PutMetricData(&cloudwatch.PutMetricDataInput{
				Namespace:  aws.String(cw.namespace),
				MetricData: batch,
			})
			errors <- err
		}(batch)
	}
	var firstErr error
	for i := 0; i < cap(errors); i++ {
		if err := <-errors; err != nil && firstErr != nil {
			firstErr = err
		}
	}

	return firstErr
}
1124567
func (c *Client) Ping() (bool, error) {
	cmd := &PingCommand{}
	err := c.cluster.Execute(cmd)
	return cmd.Success(), err
}
314164
func (t *Ticker) Run() {
	// predeclare some vars
	var (
		i, pos, nameLen int
		v               byte
		n               uint64
		err             error
	)
	// ticker
Tick:
	for {
		select {
		case <-t.Done:
			return
		case <-t.C:
			t.Builder.Reset()
			err = t.Profiler.Profiler.Reset()
			if err != nil {
				t.Errs <- err
				continue
			}
			structs.InfoStart(t.Builder)
			structs.InfoAddTimestamp(t.Builder, time.Now().UTC().UnixNano())
			for {
				t.Val = t.Val[:0]
				t.Line, err = t.ReadSlice('\n')
				if err != nil {
					if err == io.EOF {
						break
					}
					// An error results in sending error message and stop processing of this tick.
					t.Errs <- &joe.ReadError{Err: err}
					continue Tick
				}
				// first grab the key name (everything up to the ':')
				for i, v = range t.Line {
					if v == 0x3A {
						t.Val = t.Line[:i]
						pos = i + 1 // skip the :
						break
					}
				}
				nameLen = len(t.Val)
				// skip all spaces
				for i, v = range t.Line[pos:] {
					if v != 0x20 {
						pos += i
						break
					}
				}

				// grab the numbers
				for _, v = range t.Line[pos:] {
					if v == 0x20 || v == '\n' {
						break
					}
					t.Val = append(t.Val, v)
				}
				// any conversion error results in 0
				n, err = helpers.ParseUint(t.Val[nameLen:])
				if err != nil {
					t.Errs <- &joe.ParseError{Info: string(t.Val[:nameLen]), Err: err}
					continue
				}
				v = t.Val[0]
				if v == 'A' {
					if t.Val[5] == 'e' {
						if nameLen == 6 {
							structs.InfoAddActive(t.Builder, n)
							continue
						}
						if t.Val[7] == 'a' {
							structs.InfoAddActiveAnon(t.Builder, n)
							continue
						}
						structs.InfoAddActiveFile(t.Builder, n)
						continue
					}
					if nameLen == 9 {
						structs.InfoAddAnonPages(t.Builder, n)
						continue
					}
					structs.InfoAddAnonHugePages(t.Builder, n)
					continue
				}
				if v == 'C' {
					if nameLen == 6 {
						structs.InfoAddCached(t.Builder, n)
						continue
					}
					if nameLen == 11 {
						structs.InfoAddCommitLimit(t.Builder, n)
						continue
					}
					structs.InfoAddCommittedAS(t.Builder, n)
					continue
				}
				if v == 'D' {
					if nameLen == 5 {
						structs.InfoAddDirty(t.Builder, n)
						continue
					}
					if t.Val[10] == 'k' {
						structs.InfoAddDirectMap4K(t.Builder, n)
						continue
					}
					structs.InfoAddDirectMap2M(t.Builder, n)
					continue
				}
				if v == 'H' {
					if nameLen == 14 {
						if t.Val[10] == 'F' {
							structs.InfoAddHugePagesFree(t.Builder, n)
							continue
						}
						if t.Val[10] == 'R' {
							structs.InfoAddHugePagesRsvd(t.Builder, n)
							continue
						}
						structs.InfoAddHugePagesSurp(t.Builder, n)
					}
					if t.Val[1] == 'a' {
						structs.InfoAddHardwareCorrupted(t.Builder, n)
						continue
					}
					if t.Val[9] == 'i' {
						structs.InfoAddHugePagesSize(t.Builder, n)
						continue
					}
					structs.InfoAddHugePagesTotal(t.Builder, n)
					continue
				}
				if v == 'I' {
					if nameLen == 8 {
						structs.InfoAddInactive(t.Builder, n)
						continue
					}
					if t.Val[9] == 'a' {
						structs.InfoAddInactiveAnon(t.Builder, n)
						continue
					}
					structs.InfoAddInactiveFile(t.Builder, n)
				}
				if v == 'M' {
					v = t.Val[3]
					if nameLen < 8 {
						if v == 'p' {
							structs.InfoAddMapped(t.Builder, n)
							continue
						}
						if v == 'F' {
							structs.InfoAddMemFree(t.Builder, n)
							continue
						}
						structs.InfoAddMlocked(t.Builder, n)
						continue
					}
					if v == 'A' {
						structs.InfoAddMemAvailable(t.Builder, n)
						continue
					}
					structs.InfoAddMemTotal(t.Builder, n)
					continue
				}
				if v == 'S' {
					v = t.Val[1]
					if v == 'w' {
						if t.Val[4] == 'C' {
							structs.InfoAddSwapCached(t.Builder, n)
							continue
						}
						if t.Val[4] == 'F' {
							structs.InfoAddSwapFree(t.Builder, n)
							continue
						}
						structs.InfoAddSwapTotal(t.Builder, n)
						continue
					}
					if v == 'h' {
						structs.InfoAddShmem(t.Builder, n)
						continue
					}
					if v == 'l' {
						structs.InfoAddSlab(t.Builder, n)
						continue
					}
					if v == 'R' {
						structs.InfoAddSReclaimable(t.Builder, n)
						continue
					}
					structs.InfoAddSUnreclaim(t.Builder, n)
					continue
				}
				if v == 'V' {
					if t.Val[8] == 'C' {
						structs.InfoAddVmallocChunk(t.Builder, n)
						continue
					}
					if t.Val[8] == 'T' {
						structs.InfoAddVmallocTotal(t.Builder, n)
						continue
					}
					structs.InfoAddVmallocUsed(t.Builder, n)
					continue
				}
				if v == 'W' {
					if nameLen == 9 {
						structs.InfoAddWriteback(t.Builder, n)
						continue
					}
					structs.InfoAddWritebackTmp(t.Builder, n)
					continue
				}
				if v == 'B' {
					if nameLen == 6 {
						structs.InfoAddBounce(t.Builder, n)
						continue
					}
					structs.InfoAddBuffers(t.Builder, n)
					continue
				}
				if v == 'K' {
					structs.InfoAddKernelStack(t.Builder, n)
					continue
				}
				if v == 'N' {
					structs.InfoAddNFSUnstable(t.Builder, n)
					continue
				}
				if v == 'P' {
					structs.InfoAddPageTables(t.Builder, n)
				}
				structs.InfoAddUnevictable(t.Builder, n)
			}
			t.Builder.Finish(structs.InfoEnd(t.Builder))
			t.Data <- t.Profiler.Builder.Bytes[t.Builder.Head():]
		}
	}
}
369340
func (c *ClusterClient) reaper(idleCheckFrequency time.Duration) {
	ticker := time.NewTicker(idleCheckFrequency)
	defer ticker.Stop()

	for range ticker.C {
		nodes, err := c.nodes.All()
		if err != nil {
			break
		}

		for _, node := range nodes {
			_, err := node.Client.connPool.(*pool.ConnPool).ReapStaleConns()
			if err != nil {
				internal.Logf("ReapStaleConns failed: %s", err)
			}
		}
	}
}
276283
func (ind *VarWithoutStorage) ReceiveTick(tickData float64, streamBarIndex int) {
	ind.periodHistory.PushBack(tickData)
	firstValue := ind.periodHistory.Front().Value.(float64)

	previousMean := ind.mean
	previousVar := ind.variance

	if ind.periodCounter < ind.timePeriod {
		ind.periodCounter += 1
		delta := tickData - previousMean
		ind.mean = previousMean + delta/float64(ind.periodCounter)

		ind.variance = previousVar + delta*(tickData-ind.mean)
	} else {
		delta := tickData - firstValue
		dOld := firstValue - previousMean
		ind.mean = previousMean + delta/float64(ind.periodCounter)
		dNew := tickData - ind.mean
		ind.variance = previousVar + (dOld+dNew)*(delta)
	}

	if ind.periodHistory.Len() > ind.timePeriod {
		first := ind.periodHistory.Front()
		ind.periodHistory.Remove(first)
	}

	if ind.periodCounter >= ind.timePeriod {

		result := ind.variance / float64(ind.timePeriod)

		ind.UpdateIndicatorWithNewValue(result, streamBarIndex)
	}
}
880446
func (m *MockMetricsCollector) PingFailureCount(arg0 string) prometheus.Counter {
	ret := m.ctrl.Call(m, "PingFailureCount", arg0)
	ret0, _ := ret[0].(prometheus.Counter)
	return ret0
}
991565
func (f *FSM) Tick(decisionTask *swf.PollForDecisionTaskOutput) (*FSMContext, []*swf.Decision, *SerializedState, error) {
	//BeforeDecision interceptor invocation
	if f.DecisionInterceptor != nil {
		f.DecisionInterceptor.BeforeTask(decisionTask)
	}
	lastEvents := f.findLastEvents(*decisionTask.PreviousStartedEventId, decisionTask.Events)
	outcome := new(Outcome)
	context := NewFSMContext(f,
		*decisionTask.WorkflowType,
		*decisionTask.WorkflowExecution,
		nil,
		"", nil, uint64(0),
	)

	serializedState, err := f.findSerializedState(decisionTask.Events)
	if err != nil {
		f.FSMErrorReporter.ErrorFindingStateData(decisionTask, err)
		if f.AllowPanics {
			panic(err)
		}
		return nil, nil, nil, errors.Trace(err)
	}
	eventCorrelator, err := f.findSerializedEventCorrelator(decisionTask.Events)
	if err != nil {
		f.FSMErrorReporter.ErrorFindingCorrelator(decisionTask, err)
		if f.AllowPanics {
			panic(err)
		}
		return nil, nil, nil, errors.Trace(err)
	}
	context.eventCorrelator = eventCorrelator

	f.clog(context, "action=tick at=find-serialized-state state=%s", serializedState.StateName)

	if outcome.Data == nil && outcome.State == "" {
		data := f.zeroStateData()
		if err = f.Serializer.Deserialize(serializedState.StateData, data); err != nil {
			f.FSMErrorReporter.ErrorDeserializingStateData(decisionTask, serializedState.StateData, err)
			if f.AllowPanics {
				panic(err)
			}
			return nil, nil, nil, errors.Trace(err)
		}
		f.clog(context, "action=tick at=find-current-data data=%v", data)
		outcome.Data = data
		outcome.State = serializedState.StateName
		context.stateVersion = serializedState.StateVersion
		// BeforeDecisionContext interceptor invocation
		if f.DecisionInterceptor != nil {
			before := &Outcome{Data: outcome.Data, Decisions: outcome.Decisions, State: outcome.State}
			f.DecisionInterceptor.BeforeDecision(decisionTask, context, before)
			outcome.State = before.State
			outcome.Decisions = before.Decisions
			outcome.Data = before.Data
		}
	}

	errorState, err := f.findSerializedErrorState(decisionTask.Events)
	if errorState != nil {
		recovery, err := f.ErrorStateTick(decisionTask, errorState, context, outcome.Data)
		if recovery != nil {
			outcome = recovery
		} else {
			logf(context, "at=error-recovery-failed error=%q", err)
			//bump the unprocessed window, and re-record the error marker
			errorState.LatestUnprocessedEventId = *decisionTask.StartedEventId
			final, serializedState, err := f.recordStateMarkers(context, outcome, eventCorrelator, errorState)
			//update Error State Marker and exit with 3 marker decisions
			return context, final, serializedState, err
		}
	}

	//iterate through events oldest to newest, calling the decider for the current state.
	//if the outcome changes the state use the right FSMState
	for i := len(lastEvents) - 1; i >= 0; i-- {
		e := lastEvents[i]
		f.clog(context, "action=tick at=history id=%d type=%s", *e.EventId, *e.EventType)
		fsmState, ok := f.states[outcome.State]
		if ok {
			context.State = outcome.State
			context.stateData = outcome.Data
			//stash a copy of the state before the decision in case we need to call the error handler

			stashed := f.stasher.Stash(outcome.Data)

			anOutcome, err := f.panicSafeDecide(fsmState, context, e, outcome.Data)
			if err != nil {
				stashedData := f.zeroStateData()
				f.stasher.Unstash(stashed, stashedData)
				handler := f.errorHandlers[fsmState.Name]
				if handler == nil {
					handler = f.DecisionErrorHandler
				}
				rescued, notRescued := handler(context, e, stashedData, outcome.Data, err)
				if rescued != nil {
					anOutcome = *rescued
				} else {
					notRescuedSerialized := ""
					if notRescued != nil {
						notRescuedSerialized = notRescued.Error()
					}
					errorState := &SerializedErrorState{
						Details:                    notRescuedSerialized,
						ErrorEvent:                 e,
						EarliestUnprocessedEventId: *decisionTask.PreviousStartedEventId + 1,
						LatestUnprocessedEventId:   *decisionTask.StartedEventId,
					}
					final, serializedState, err := f.recordStateMarkers(context, outcome, eventCorrelator, errorState)
					if err != nil {
						f.FSMErrorReporter.ErrorSerializingStateData(decisionTask, *outcome, *eventCorrelator, err)
						if f.AllowPanics {
							panic(err)
						}
						return nil, nil, nil, errors.Trace(err)
					}
					return context, final, serializedState, nil
				}
			}
			//NOTE this call is handled in fsmContext.Decide. The double call causes nil panics
			//eventCorrelator.Track(e)
			curr := outcome.State
			f.mergeOutcomes(outcome, anOutcome)
			f.clog(context, "action=tick at=decided-event state=%s next-state=%s decisions=%d", curr, outcome.State, len(anOutcome.Decisions))
		} else {
			f.FSMErrorReporter.ErrorMissingFSMState(decisionTask, *outcome)
			return nil, nil, nil, errors.New("marked-state-not-in-fsm state=" + outcome.State)
		}
	}

	f.clog(context, "action=tick at=events-processed next-state=%s decisions=%d", outcome.State, len(outcome.Decisions))

	for _, d := range outcome.Decisions {
		f.clog(context, "action=tick at=decide next-state=%s decision=%s", outcome.State, *d.DecisionType)
	}
	//AfterDecision interceptor invocation
	if f.DecisionInterceptor != nil {
		context.State = outcome.State
		context.stateData = outcome.Data
		after := &Outcome{Data: outcome.Data, Decisions: outcome.Decisions, State: outcome.State}
		f.DecisionInterceptor.AfterDecision(decisionTask, context, after)
		outcome.State = after.State
		outcome.Decisions = after.Decisions
		outcome.Data = after.Data
	}

	final, serializedState, err := f.recordStateMarkers(context, outcome, context.eventCorrelator, nil)
	if err != nil {
		f.FSMErrorReporter.ErrorSerializingStateData(decisionTask, *outcome, *eventCorrelator, err)
		if f.AllowPanics {
			panic(err)
		}
		return nil, nil, nil, errors.Trace(err)
	}

	return context, final, serializedState, nil
}
1072030
func (s *StatsdSink) flushMetrics() {
	var sock net.Conn
	var err error
	var wait <-chan time.Time
	ticker := time.NewTicker(flushInterval)
	defer ticker.Stop()

CONNECT:
	// Create a buffer
	buf := bytes.NewBuffer(nil)

	// Attempt to connect
	sock, err = net.Dial("udp", s.addr)
	if err != nil {
		log.Printf("[ERR] Error connecting to statsd! Err: %s", err)
		goto WAIT
	}

	for {
		select {
		case metric, ok := <-s.metricQueue:
			// Get a metric from the queue
			if !ok {
				goto QUIT
			}

			// Check if this would overflow the packet size
			if len(metric)+buf.Len() > statsdMaxLen {
				_, err := sock.Write(buf.Bytes())
				buf.Reset()
				if err != nil {
					log.Printf("[ERR] Error writing to statsd! Err: %s", err)
					goto WAIT
				}
			}

			// Append to the buffer
			buf.WriteString(metric)

		case <-ticker.C:
			if buf.Len() == 0 {
				continue
			}

			_, err := sock.Write(buf.Bytes())
			buf.Reset()
			if err != nil {
				log.Printf("[ERR] Error flushing to statsd! Err: %s", err)
				goto WAIT
			}
		}
	}

WAIT:
	// Wait for a while
	wait = time.After(time.Duration(5) * time.Second)
	for {
		select {
		// Dequeue the messages to avoid backlog
		case _, ok := <-s.metricQueue:
			if !ok {
				goto QUIT
			}
		case <-wait:
			goto CONNECT
		}
	}
QUIT:
	s.metricQueue = nil
}
797899
func (tr *TaskReaper) tick() {
	// this signals that a tick has occurred. it exists solely for testing.
	if tr.tickSignal != nil {
		// try writing to this channel, but if it's full, fall straight through
		// and ignore it.
		select {
		case tr.tickSignal <- struct{}{}:
		default:
		}
	}

	if len(tr.dirty) == 0 && len(tr.cleanup) == 0 {
		return
	}

	defer func() {
		tr.cleanup = nil
	}()

	deleteTasks := make(map[string]struct{})
	for _, tID := range tr.cleanup {
		deleteTasks[tID] = struct{}{}
	}

	// Check history of dirty tasks for cleanup.
	// Note: Clean out the dirty set at the end of this tick iteration
	// in all but one scenarios (documented below).
	// When tick() finishes, the tasks in the slot were either cleaned up,
	// or it was skipped because it didn't meet the criteria for cleaning.
	// Either way, we can discard the dirty set because future events on
	// that slot will cause the task to be readded to the dirty set
	// at that point.
	//
	// The only case when we keep the slot dirty is when there are more
	// than one running tasks present for a given slot.
	// In that case, we need to keep the slot dirty to allow it to be
	// cleaned when tick() is called next and one or more the tasks
	// in that slot have stopped running.
	tr.store.View(func(tx store.ReadTx) {
		for dirty := range tr.dirty {
			service := store.GetService(tx, dirty.ServiceID)
			if service == nil {
				delete(tr.dirty, dirty)
				continue
			}

			taskHistory := tr.taskHistory

			// If MaxAttempts is set, keep at least one more than
			// that number of tasks (this overrides TaskHistoryRetentionLimit).
			// This is necessary to reconstruct restart history when the orchestrator starts up.
			// TODO(aaronl): Consider hiding tasks beyond the normal
			// retention limit in the UI.
			// TODO(aaronl): There are some ways to cut down the
			// number of retained tasks at the cost of more
			// complexity:
			//   - Don't force retention of tasks with an older spec
			//     version.
			//   - Don't force retention of tasks outside of the
			//     time window configured for restart lookback.
			if service.Spec.Task.Restart != nil && service.Spec.Task.Restart.MaxAttempts > 0 {
				taskHistory = int64(service.Spec.Task.Restart.MaxAttempts) + 1
			}

			// Negative value for TaskHistoryRetentionLimit is an indication to never clean up task history.
			if taskHistory < 0 {
				delete(tr.dirty, dirty)
				continue
			}

			var historicTasks []*api.Task

			switch service.Spec.GetMode().(type) {
			case *api.ServiceSpec_Replicated:
				// Clean out the slot for which we received EventCreateTask.
				var err error
				historicTasks, err = store.FindTasks(tx, store.BySlot(dirty.ServiceID, dirty.Slot))
				if err != nil {
					continue
				}

			case *api.ServiceSpec_Global:
				// Clean out the node history in case of global services.
				tasksByNode, err := store.FindTasks(tx, store.ByNodeID(dirty.NodeID))
				if err != nil {
					continue
				}

				for _, t := range tasksByNode {
					if t.ServiceID == dirty.ServiceID {
						historicTasks = append(historicTasks, t)
					}
				}
			}

			if int64(len(historicTasks)) <= taskHistory {
				delete(tr.dirty, dirty)
				continue
			}

			// TODO(aaronl): This could filter for non-running tasks and use quickselect
			// instead of sorting the whole slice.
			// TODO(aaronl): This sort should really use lamport time instead of wall
			// clock time. We should store a Version in the Status field.
			sort.Sort(orchestrator.TasksByTimestamp(historicTasks))

			runningTasks := 0
			for _, t := range historicTasks {
				// Historical tasks can be considered for cleanup if:
				// 1. The task has reached a terminal state i.e. actual state beyond TaskStateRunning.
				// 2. The task has not yet become running and desired state is a terminal state i.e.
				// actual state not yet TaskStateAssigned and desired state beyond TaskStateRunning.
				if taskInTerminalState(t) || taskWillNeverRun(t) {
					deleteTasks[t.ID] = struct{}{}

					taskHistory++
					if int64(len(historicTasks)) <= taskHistory {
						break
					}
				} else {
					// all other tasks are counted as running.
					runningTasks++
				}
			}

			// The only case when we keep the slot dirty at the end of tick()
			// is when there are more than one running tasks present
			// for a given slot.
			// In that case, we keep the slot dirty to allow it to be
			// cleaned when tick() is called next and one or more of
			// the tasks in that slot have stopped running.
			if runningTasks <= 1 {
				delete(tr.dirty, dirty)
			}
		}
	})

	// Perform cleanup.
	if len(deleteTasks) > 0 {
		tr.store.Batch(func(batch *store.Batch) error {
			for taskID := range deleteTasks {
				batch.Update(func(tx store.Tx) error {
					return store.DeleteTask(tx, taskID)
				})
			}
			return nil
		})
	}
}
817494
func ticker(d time.Duration) chan struct{} {
	t := time.NewTicker(d)
	stop := make(chan struct{})
	go func() {
		for {
			select {
			case <-t.C:
				log.Printf("tick (just for keeping CI job active) per %s", d.String())
			case <-stop:
				t.Stop()
			}
		}
	}()
	return stop
}
19475
func (t Ticks) Less(i, j int) bool {
	return t[i].Value < t[j].Value
}
465722
func (c *Clock) Tick() {
	currStamp := theTimer.Now()

	c.counter++

	c.deltaStamp = currStamp - c.frameStamp
	c.frameStamp = currStamp

	c.elapsStamp += c.deltaStamp
	if secondsInNano <= c.elapsStamp {
		c.elapsStamp %= secondsInNano
		c.perSecond = c.counter
		c.counter = 0
	}
}