Example #1
0
func (provider *ConsulCatalog) healthyNodes(service string) (catalogUpdate, error) {
	health := provider.client.Health()
	opts := &api.QueryOptions{}
	data, _, err := health.Service(service, "", true, opts)
	if err != nil {
		log.WithError(err).Errorf("Failed to fetch details of " + service)
		return catalogUpdate{}, err
	}

	nodes := fun.Filter(func(node *api.ServiceEntry) bool {
		constraintTags := provider.getContraintTags(node.Service.Tags)
		ok, failingConstraint := provider.MatchConstraints(constraintTags)
		if ok == false && failingConstraint != nil {
			log.Debugf("Service %v pruned by '%v' constraint", service, failingConstraint.String())
		}
		return ok
	}, data).([]*api.ServiceEntry)

	//Merge tags of nodes matching constraints, in a single slice.
	tags := fun.Foldl(func(node *api.ServiceEntry, set []string) []string {
		return fun.Keys(fun.Union(
			fun.Set(set),
			fun.Set(node.Service.Tags),
		).(map[string]bool)).([]string)
	}, []string{}, nodes).([]string)

	return catalogUpdate{
		Service: &serviceUpdate{
			ServiceName: service,
			Attributes:  tags,
		},
		Nodes: nodes,
	}, nil
}
Example #2
0
// Returns a list of tables that have indices which are modified by updating
// the lists given.
// Each table name will only appear once.
//
// If the name/atom table has more than 0 rows, then it will not be included
// in the list returned. This prevents rebuilding the indices on each update,
// which usually contains nominal additions to the name/atom table.
func tablesFromLists(db *imdb.DB, lists []string) (tables []string, err error) {
	var pre []string
	for _, name := range lists {
		tablesForList, ok := listTables[name]
		if !ok {
			return nil, ef("BUG: Could not find tables for list %s", name)
		}
		pre = append(pre, tablesForList...)
	}
	pre = fun.Keys(fun.Set(pre)).([]string)

	updatingEmpty := func(table string) bool {
		return rowCount(db, table) == 0 && fun.In(table, pre)
	}
	for _, table := range pre {
		switch table {
		case "atom", "name":
			// This is a little complex. Basically, we want to avoid rebuilding
			// indices for incremental updates. So we only let it happen when
			// we're updating the actor or movie lists from scratch.
			// (In general, this should apply to any table that is updated
			// concurrently with name/atom. We exclude tvshow and episode since
			// they are only updated when movie is updated.)
			if updatingEmpty("actor") || updatingEmpty("movie") {
				tables = append(tables, table)
			}
		default:
			tables = append(tables, table)
		}
	}
	return
}