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 }
// 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 }