github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/context/cache.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package context
     5  
     6  import (
     7  	"sort"
     8  
     9  	"github.com/juju/juju/apiserver/params"
    10  )
    11  
    12  // SettingsFunc returns the relation settings for a unit.
    13  type SettingsFunc func(unitName string) (params.Settings, error)
    14  
    15  // SettingsMap is a map from unit name to relation settings.
    16  type SettingsMap map[string]params.Settings
    17  
    18  // RelationCache stores a relation's remote unit membership and settings.
    19  // Member settings are stored until invalidated or removed by name; settings
    20  // of non-member units are stored only until the cache is pruned.
    21  type RelationCache struct {
    22  	// readSettings is used to get settings data if when not already present.
    23  	readSettings SettingsFunc
    24  	// members' keys define the relation's membership; non-nil values hold
    25  	// cached settings.
    26  	members SettingsMap
    27  	// others is a short-term cache for non-member settings.
    28  	others SettingsMap
    29  }
    30  
    31  // NewRelationCache creates a new RelationCache that will use the supplied
    32  // SettingsFunc to populate itself on demand. Initial membership is determined
    33  // by memberNames.
    34  func NewRelationCache(readSettings SettingsFunc, memberNames []string) *RelationCache {
    35  	cache := &RelationCache{
    36  		readSettings: readSettings,
    37  	}
    38  	cache.Prune(memberNames)
    39  	return cache
    40  }
    41  
    42  // Prune resets the membership to the supplied list, and discards the settings
    43  // of all non-member units.
    44  func (cache *RelationCache) Prune(memberNames []string) {
    45  	newMembers := SettingsMap{}
    46  	for _, memberName := range memberNames {
    47  		newMembers[memberName] = cache.members[memberName]
    48  	}
    49  	cache.members = newMembers
    50  	cache.others = SettingsMap{}
    51  }
    52  
    53  // MemberNames returns the names of the remote units present in the relation.
    54  func (cache *RelationCache) MemberNames() (memberNames []string) {
    55  	for memberName := range cache.members {
    56  		memberNames = append(memberNames, memberName)
    57  	}
    58  	sort.Strings(memberNames)
    59  	return memberNames
    60  }
    61  
    62  // Settings returns the settings of the named remote unit. It's valid to get
    63  // the settings of any unit that has ever been in the relation.
    64  func (cache *RelationCache) Settings(unitName string) (params.Settings, error) {
    65  	settings, isMember := cache.members[unitName]
    66  	if settings == nil {
    67  		if !isMember {
    68  			settings = cache.others[unitName]
    69  		}
    70  		if settings == nil {
    71  			var err error
    72  			settings, err = cache.readSettings(unitName)
    73  			if err != nil {
    74  				return nil, err
    75  			}
    76  		}
    77  	}
    78  	if isMember {
    79  		cache.members[unitName] = settings
    80  	} else {
    81  		cache.others[unitName] = settings
    82  	}
    83  	return settings, nil
    84  }
    85  
    86  // InvalidateMember ensures that the named remote unit will be considered a
    87  // member of the relation, and that the next attempt to read its settings will
    88  // use fresh data.
    89  func (cache *RelationCache) InvalidateMember(memberName string) {
    90  	cache.members[memberName] = nil
    91  }
    92  
    93  // RemoveMember ensures that the named remote unit will not be considered a
    94  // member of the relation,
    95  func (cache *RelationCache) RemoveMember(memberName string) {
    96  	delete(cache.members, memberName)
    97  }