Example #1
0
func (*statusContext) processRelations(service *state.Service) (related map[string][]string, subord []string, err error) {
	// TODO(mue) This way the same relation is read twice (for each service).
	// Maybe add Relations() to state, read them only once and pass them to each
	// call of this function.
	relations, err := service.Relations()
	if err != nil {
		return nil, nil, err
	}
	var subordSet set.Strings
	related = make(map[string][]string)
	for _, relation := range relations {
		ep, err := relation.Endpoint(service.Name())
		if err != nil {
			return nil, nil, err
		}
		relationName := ep.Relation.Name
		eps, err := relation.RelatedEndpoints(service.Name())
		if err != nil {
			return nil, nil, err
		}
		for _, ep := range eps {
			if ep.Scope == charm.ScopeContainer && !service.IsPrincipal() {
				subordSet.Add(ep.ServiceName)
			}
			related[relationName] = append(related[relationName], ep.ServiceName)
		}
	}
	for relationName, serviceNames := range related {
		sn := set.NewStrings(serviceNames...)
		related[relationName] = sn.SortedValues()
	}
	return related, subordSet.SortedValues(), nil
}
Example #2
0
// collect calls f on all values in src and returns an alphabetically
// ordered list of the returned results without duplicates.
func (src List) collect(f func(*Tools) string) []string {
	var seen set.Strings
	for _, tools := range src {
		seen.Add(f(tools))
	}
	return seen.SortedValues()
}
Example #3
0
func (stringSetSuite) TestUninitialized(c *C) {
	var uninitialized set.Strings
	c.Assert(uninitialized.Size(), Equals, 0)
	c.Assert(uninitialized.IsEmpty(), Equals, true)
	// You can get values and sorted values from an unitialized set.
	AssertValues(c, uninitialized)
	// All contains checks are false
	c.Assert(uninitialized.Contains("foo"), Equals, false)
	// Remove works on an uninitialized Strings
	uninitialized.Remove("foo")

	var other set.Strings
	// Union returns a new set that is empty but initialized.
	c.Assert(uninitialized.Union(other), DeepEquals, set.NewStrings())
	c.Assert(uninitialized.Intersection(other), DeepEquals, set.NewStrings())
	c.Assert(uninitialized.Difference(other), DeepEquals, set.NewStrings())

	other = set.NewStrings("foo", "bar")
	c.Assert(uninitialized.Union(other), DeepEquals, other)
	c.Assert(uninitialized.Intersection(other), DeepEquals, set.NewStrings())
	c.Assert(uninitialized.Difference(other), DeepEquals, set.NewStrings())
	c.Assert(other.Union(uninitialized), DeepEquals, other)
	c.Assert(other.Intersection(uninitialized), DeepEquals, set.NewStrings())
	c.Assert(other.Difference(uninitialized), DeepEquals, other)

	// Once something is added, the set becomes initialized.
	uninitialized.Add("foo")
	AssertValues(c, uninitialized, "foo")
}
Example #4
0
func (w *minUnitsWatcher) initial() (*set.Strings, error) {
	serviceNames := new(set.Strings)
	doc := &minUnitsDoc{}
	iter := w.st.minUnits.Find(nil).Iter()
	for iter.Next(doc) {
		w.known[doc.ServiceName] = doc.Revno
		serviceNames.Add(doc.ServiceName)
	}
	return serviceNames, iter.Err()
}
Example #5
0
func (w *minUnitsWatcher) merge(serviceNames *set.Strings, change watcher.Change) error {
	serviceName := change.Id.(string)
	if change.Revno == -1 {
		delete(w.known, serviceName)
		serviceNames.Remove(serviceName)
		return nil
	}
	doc := minUnitsDoc{}
	if err := w.st.minUnits.FindId(serviceName).One(&doc); err != nil {
		return err
	}
	revno, known := w.known[serviceName]
	w.known[serviceName] = doc.Revno
	if !known || doc.Revno > revno {
		serviceNames.Add(serviceName)
	}
	return nil
}
Example #6
0
func (w *lifecycleWatcher) merge(ids *set.Strings, updates map[string]bool) error {
	// Separate ids into those thought to exist and those known to be removed.
	changed := []string{}
	latest := map[string]Life{}
	for id, exists := range updates {
		if exists {
			changed = append(changed, id)
		} else {
			latest[id] = Dead
		}
	}

	// Collect life states from ids thought to exist. Any that don't actually
	// exist are ignored (we'll hear about them in the next set of updates --
	// all that's actually happened in that situation is that the watcher
	// events have lagged a little behind reality).
	iter := w.coll.Find(D{{"_id", D{{"$in", changed}}}}).Select(lifeFields).Iter()
	var doc lifeDoc
	for iter.Next(&doc) {
		latest[doc.Id] = doc.Life
	}
	if err := iter.Err(); err != nil {
		return err
	}

	// Add to ids any whose life state is known to have changed.
	for id, newLife := range latest {
		gone := newLife == Dead
		oldLife, known := w.life[id]
		switch {
		case known && gone:
			delete(w.life, id)
		case !known && !gone:
			w.life[id] = newLife
		case known && newLife != oldLife:
			w.life[id] = newLife
		default:
			continue
		}
		ids.Add(id)
	}
	return nil
}
Example #7
0
// fetchUnitMachineIds returns a set of IDs for machines that
// the specified units reside on, and those machines' ancestors.
func fetchUnitMachineIds(units map[string]map[string]*state.Unit) (*set.Strings, error) {
	machineIds := new(set.Strings)
	for _, svcUnitMap := range units {
		for _, unit := range svcUnitMap {
			if !unit.IsPrincipal() {
				continue
			}
			mid, err := unit.AssignedMachineId()
			if err != nil {
				return nil, err
			}
			for mid != "" {
				machineIds.Add(mid)
				mid = state.ParentId(mid)
			}
		}
	}
	return machineIds, nil
}