// Done outputs the group to screen
160755
func (g *group) Done() {
	g.log.output(g.quiet, g.lines...)
}
1285688
func (m *Interactions) Done(id string, loginUser names.UserTag, loginError error) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	item := m.items[id]

	if item == nil {
		return errors.NotFoundf("interaction %q", id)
	}
	if item.done {
		return errors.Errorf("interaction %q already done", id)
	}
	item.done = true
	item.c <- Interaction{
		CaveatId:   item.caveatId,
		LoginUser:  loginUser,
		LoginError: loginError,
	}
	return nil
}
623326
func (op *DestroyUnitOperation) Done(err error) error {
	if err != nil {
		if !op.Force {
			return errors.Annotatef(err, "cannot destroy unit %q", op.unit)
		}
		op.AddError(errors.Errorf("force destroy unit %q proceeded despite encountering ERROR %v", op.unit, err))
	}
	if err := op.eraseHistory(); err != nil {
		if !op.Force {
			logger.Errorf("cannot delete history for unit %q: %v", op.unit.globalKey(), err)
		}
		op.AddError(errors.Errorf("force erase unit's %q history proceeded despite encountering ERROR %v", op.unit.globalKey(), err))
	}
	return nil
}
106669
func (s *StreamingSession) Finished() (bool, error) {
	s.Lock()
	err := s.err
	fin := s.finished
	s.Unlock()

	return fin, err
}
844374
func (op *AddUnitOperation) Done(err error) error {
	if err != nil {
		return errors.Annotatef(err, "adding unit to %q", op.application.Name())
	}
	if op.props.AgentStatus == nil && op.props.CloudContainerStatus == nil {
		return nil
	}
	// We do a separate status update here because we require all units to be
	// created as "allocating". If the add operation specifies a status,
	// that status is used to update the initial "allocating" status. We then
	// get the expected 2 status entries in history. This is done in a separate
	// transaction; a failure here will effectively be retried because the worker
	// which has made the API call will restart and then perform the necessary update..
	u, err := op.application.st.Unit(op.unitName)
	if err != nil {
		return errors.Trace(err)
	}
	if op.props.AgentStatus != nil {
		now := op.application.st.clock().Now()
		if err := u.Agent().SetStatus(status.StatusInfo{
			Status:  op.props.AgentStatus.Status,
			Message: op.props.AgentStatus.Message,
			Data:    op.props.AgentStatus.Data,
			Since:   &now,
		}); err != nil {
			return errors.Trace(err)
		}
	}
	if op.props.CloudContainerStatus != nil {
		doc := statusDoc{
			Status:     op.props.CloudContainerStatus.Status,
			StatusInfo: op.props.CloudContainerStatus.Message,
			StatusData: mgoutils.EscapeKeys(op.props.CloudContainerStatus.Data),
			Updated:    timeOrNow(op.props.CloudContainerStatus.Since, u.st.clock()).UnixNano(),
		}
		_, err := probablyUpdateStatusHistory(op.application.st.db(), globalCloudContainerKey(op.unitName), doc)
		if err != nil {
			return errors.Trace(err)
		}

		// Ensure unit history is updated correctly
		unitStatus, err := getStatus(op.application.st.db(), unitGlobalKey(op.unitName), "unit")
		if err != nil {
			return errors.Trace(err)
		}
		newHistory, err := caasHistoryRewriteDoc(unitStatus, *op.props.CloudContainerStatus, true, caasUnitDisplayStatus, op.application.st.clock())
		if err != nil {
			return errors.Trace(err)
		}
		if newHistory != nil {
			err = setStatus(op.application.st.db(), setStatusParams{
				badge:            "unit",
				globalKey:        unitGlobalKey(op.unitName),
				status:           unitStatus.Status,
				message:          unitStatus.Message,
				rawData:          unitStatus.Data,
				updated:          timeOrNow(unitStatus.Since, u.st.clock()),
				historyOverwrite: newHistory,
			})
		}
	}

	return nil
}
1021431
func (s *DurationRatioStat) Done(k interface{}) {
	s.m.Lock()
	defer s.m.Unlock()
	if !s.isStarted {
		return
	}
	s.d += time.Now().Sub(s.startedAt[k])
	delete(s.startedAt, k)
}
1280681
func (s *Sleeper) Done() {
	// Remove all associations that we can, and build a list of the ones
	// we could not. An association can be removed right away from waker w
	// if w.s has a pointer to the sleeper, that is, the waker is not
	// asserted yet. By atomically switching w.s to nil, we guarantee that
	// subsequent calls to Assert() on the waker will not result in it being
	// queued to this sleeper.
	var pending *Waker
	w := s.allWakers
	for w != nil {
		next := w.allWakersNext
		for {
			t := atomic.LoadPointer(&w.s)
			if t != usleeper(s) {
				w.allWakersNext = pending
				pending = w
				break
			}

			if atomic.CompareAndSwapPointer(&w.s, t, nil) {
				break
			}
		}
		w = next
	}

	// The associations that we could not remove are either asserted, or in
	// the process of being asserted, or have been asserted and cleared
	// before being pulled from the sleeper lists. We must wait for them all
	// to make it to the sleeper lists, so that we know that the wakers
	// won't do any more work towards waking this sleeper up.
	for pending != nil {
		pulled := s.nextWaker(true)

		// Remove the waker we just pulled from the list of associated
		// wakers.
		prev := &pending
		for w := *prev; w != nil; w = *prev {
			if pulled == w {
				*prev = w.allWakersNext
				break
			}
			prev = &w.allWakersNext
		}
	}
	s.allWakers = nil
}
439978
func (b *rescanBatch) done(err error) {
	for _, c := range b.errChans {
		c <- err
	}
}
473939
func (op *LeaveScopeOperation) Done(err error) error {
	if err != nil {
		if !op.Force {
			return errors.Annotatef(err, "%v cannot leave scope", op.Description())
		}
		op.AddError(errors.Errorf("%v tried to forcefully leave scope but proceeded despite encountering ERROR %v", op.Description(), err))
	}
	return nil
}
407466
func (g *Group) Do(ctx context.Context, key string, fn func(ctx context.Context) (interface{}, error)) (v interface{}, err error) {
	var backoff time.Duration
	for {
		v, err = g.do(ctx, key, fn)
		if err == nil || errors.Cause(err) != errRetry {
			return v, err
		}
		// backoff logic
		if backoff >= 3*time.Second {
			err = errors.Wrapf(errRetryTimeout, "flightcontrol")
			return v, err
		}
		runtime.Gosched()
		if backoff > 0 {
			time.Sleep(backoff)
			backoff *= 2
		} else {
			backoff = time.Millisecond
		}
	}
}
474462
func (m *GroupByFinal) Close() error {
	m.Lock()
	if m.closed {
		m.Unlock()
		return nil
	}
	m.closed = true
	m.Unlock()

	ticker := time.NewTicker(30 * time.Second)
	defer ticker.Stop()

	//u.Infof("%p group by final Close() waiting for complete", m)
	select {
	case <-ticker.C:
		u.Warnf("timeout???? ")
	case <-m.complete:
		//u.Warnf("%p got groupbyfinal complete", m)
	}

	return m.TaskBase.Close()
}
803751
func (ev *DoneChannel) Done(err error) {
	if ev.DoneChan != nil {
		select {
		case ev.DoneChan <- err:
			// sent successfully
		default:
			logrus.DefaultLogger().Debug("Nobody is listening anymore")
		}
	} else if err != nil {
		logrus.DefaultLogger().Error(err)
	}
}
1074217
func (l *Logs) wait(done <-chan error) {
	for range l.GroupNames {
		if err := <-done; err != nil {
			l.err = err
			return
		}
	}
}
325993
func (op *UpdateMachineOperation) Done(err error) error {
	return errors.Annotatef(err, "updating machine %q", op.m)
}
616735
func Join(doners ...Doner) C {
	var wg sync.WaitGroup
	wg.Add(len(doners))
	for _, d := range doners {
		Defer(d, wg.Done)
	}

	cq := make(chan struct{})
	go func() {
		wg.Wait()
		close(cq)
	}()
	return cq
}
442225
func (twg *TimeoutWaitGroup) Done() {
	twg.mutex.Lock()
	defer twg.mutex.Unlock()
	twg.workers--
	if twg.workers < 0 {
		panic("TimeoutWaitGroup: negative counter")
	}
	if twg.workers == 0 && twg.last != nil {
		close(twg.last)
	}
}
793371
func (j *Job) Finished() time.Time {
	return time.Unix(0, j.finished).Local()
}