Documentation ¶
Index ¶
- Constants
- type Environment
- type EnvironmentStorage
- type Flag
- type FlagEntries
- type FlagStorage
- type Pilot
- type PilotEntries
- type PilotStorage
- type PseudoRandPercentageAlgorithms
- type Rollout
- type RolloutDecisionAND
- type RolloutDecisionByAPI
- type RolloutDecisionByGlobal
- type RolloutDecisionByPercentage
- type RolloutDecisionNOT
- type RolloutDecisionOR
- type RolloutEntries
- type RolloutManager
- func (manager *RolloutManager) CreateFeatureFlag(ctx context.Context, flag *Flag) error
- func (manager *RolloutManager) DeleteFeatureFlag(ctx context.Context, id string) (returnErr error)
- func (manager *RolloutManager) GetAllReleaseFlagStatesOfThePilot(ctx context.Context, pilotExternalID string, env Environment, ...) (map[string]bool, error)
- func (manager *RolloutManager) ListFeatureFlags(ctx context.Context) ([]Flag, error)
- func (manager *RolloutManager) SetPilotEnrollmentForFeature(ctx context.Context, flagID string, envID string, externalPilotID string, ...) error
- func (manager *RolloutManager) UnsetPilotEnrollmentForFeature(ctx context.Context, flagID string, envID string, pilotExternalID string) error
- func (manager *RolloutManager) UpdateFeatureFlag(ctx context.Context, flag *Flag) error
- type RolloutPlan
- type RolloutPlanView
- func (view RolloutPlanView) MarshalJSON() ([]byte, error)
- func (view RolloutPlanView) MarshalMapping(this RolloutPlan) (map[string]interface{}, error)
- func (view *RolloutPlanView) UnmarshalJSON(bytes []byte) error
- func (view RolloutPlanView) UnmarshalMapping(data []byte) (_def RolloutPlan, rErr error)
- type RolloutStorage
- type Storage
Constants ¶
const ( ErrNameIsEmpty frameless.Error = `feature name can't be empty` ErrMissingFlag frameless.Error = `release flag is not provided` ErrMissingEnv frameless.Error = `deployment environment is not provided` ErrInvalidAction frameless.Error = `invalid rollout action` ErrFlagAlreadyExist frameless.Error = `release flag already exist` ErrInvalidRequestURL frameless.Error = `value is not a valid request url` ErrInvalidPercentage frameless.Error = `percentage value not acceptable` ErrMissingRolloutPlan frameless.Error = `release rollout plan is not provided` )
const (
ErrEnvironmentNameIsEmpty frameless.Error = `deployment environment name can't be empty`
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Environment ¶
func (Environment) Validate ¶
func (env Environment) Validate() error
type EnvironmentStorage ¶
type EnvironmentStorage interface { frameless.Creator frameless.Finder frameless.Updater frameless.Deleter frameless.CreatorPublisher frameless.UpdaterPublisher frameless.DeleterPublisher FindByAlias(ctx context.Context, idOrName string, env *Environment) (bool, error) }
type FlagEntries ¶
type FlagStorage ¶
type FlagStorage interface { frameless.Creator frameless.Finder frameless.Updater frameless.Deleter frameless.CreatorPublisher frameless.UpdaterPublisher frameless.DeleterPublisher FindByName(ctx context.Context, name string) (*Flag, error) FindByNames(ctx context.Context, names ...string) FlagEntries }
type Pilot ¶
type Pilot struct { // ID represent the fact that this object will be persistent in the Subject ID string `ext:"ID",json:"id"` // FlagID is the reference ID that can tell where this user record belongs to. FlagID string `json:"flag_id"` // EnvironmentID is the ID of the environment where the pilot should be enrolled EnvironmentID string `json:"env_id"` // PublicID is the unique id that connects the entry to the caller services, // with this service and able to use A-B/Percentage or Pilot based testings. PublicID string `json:"public_id"` // IsParticipating states that whether the pilot for the given flag in a given environment is enrolled, or blacklisted. IsParticipating bool `json:"is_participating"` }
Pilot is a data entity that represent relation between an external system's user and a feature flag. The Pilot terminology itself means that the user is in charge to try out a given feature, even if the user itself is not aware of this role.
type PilotEntries ¶
type PilotStorage ¶
type PilotStorage interface { frameless.Creator frameless.Finder frameless.Updater frameless.Deleter frameless.CreatorPublisher frameless.UpdaterPublisher frameless.DeleterPublisher FindByFlagEnvPublicID(ctx context.Context, flagID, envID interface{}, publicID string) (*Pilot, error) FindByFlag(ctx context.Context, flag Flag) PilotEntries FindByPublicID(ctx context.Context, publicID string) PilotEntries }
type PseudoRandPercentageAlgorithms ¶
type PseudoRandPercentageAlgorithms struct{}
PseudoRandPercentageAlgorithms implements pseudo random percentage calculations with different algorithms. This is mainly used for pilot enrollments when percentage strategy is used for rolloutBase.
type Rollout ¶
type Rollout struct { ID string `ext:"ID"` // FlagID is the release flag id to which the rolloutBase belongs FlagID string // EnvironmentID is the deployment environment id EnvironmentID string // Plan holds the composited rule set about the pilot participation decision logic. Plan RolloutPlan }
func (Rollout) MarshalJSON ¶
func (*Rollout) UnmarshalJSON ¶
type RolloutDecisionAND ¶
type RolloutDecisionAND struct { Left RolloutPlan `json:"left"` Right RolloutPlan `json:"right"` }
func (RolloutDecisionAND) IsParticipating ¶
func (r RolloutDecisionAND) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)
TODO:SPEC
type RolloutDecisionByAPI ¶
type RolloutDecisionByAPI struct { // URL allow you to do rolloutBase based on custom domain needs such as target groups, // which decision logic is available trough an API endpoint call URL *url.URL `json:"url"` }
func NewRolloutDecisionByAPI ¶
func NewRolloutDecisionByAPI(u *url.URL) RolloutDecisionByAPI
func NewRolloutDecisionByAPIDeprecated ¶
func NewRolloutDecisionByAPIDeprecated() RolloutDecisionByAPI
NewRolloutDecisionByAPIDeprecated DEPRECATED
func (RolloutDecisionByAPI) IsParticipating ¶
func (*RolloutDecisionByAPI) UnmarshalJSON ¶
func (s *RolloutDecisionByAPI) UnmarshalJSON(bytes []byte) error
func (RolloutDecisionByAPI) Validate ¶
func (s RolloutDecisionByAPI) Validate() error
type RolloutDecisionByGlobal ¶
type RolloutDecisionByGlobal struct {
State bool `json:"state"`
}
func NewRolloutDecisionByGlobal ¶
func NewRolloutDecisionByGlobal() RolloutDecisionByGlobal
TODO: add proper coverage
func (RolloutDecisionByGlobal) IsParticipating ¶
func (RolloutDecisionByGlobal) Validate ¶
func (r RolloutDecisionByGlobal) Validate() error
type RolloutDecisionByPercentage ¶
type RolloutDecisionByPercentage struct { // PseudoRandPercentageAlgorithm specifies the algorithm that is expected to be used in the percentage calculation. // Currently it is only supports FNV1a64 and "func" PseudoRandPercentageAlgorithm string `json:"algo"` // PseudoRandPercentageFunc is a dependency that can be used if the Algorithm is not defined or defined to func. // Ideal for testing. PseudoRandPercentageFunc func(id string, seedSalt int64) (int, error) `json:"-"` // Seed allows you to configure the randomness for the percentage based pilot enrollment selection. // This value could have been neglected by using the flag name as random seed, // but that would reduce the flexibility for edge cases where you want // to use a similar pilot group as a successful flag rolloutBase before. Seed int64 `json:"seed"` // Percentage allows you to define how many of your user base should be enrolled pseudo randomly. Percentage int `json:"percentage"` }
func NewRolloutDecisionByPercentage ¶
func NewRolloutDecisionByPercentage() RolloutDecisionByPercentage
func (RolloutDecisionByPercentage) IsParticipating ¶
func (RolloutDecisionByPercentage) Validate ¶
func (s RolloutDecisionByPercentage) Validate() error
type RolloutDecisionNOT ¶
type RolloutDecisionNOT struct {
Definition RolloutPlan `json:"def"`
}
func (RolloutDecisionNOT) IsParticipating ¶
func (r RolloutDecisionNOT) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)
TODO:SPEC
type RolloutDecisionOR ¶
type RolloutDecisionOR struct { Left RolloutPlan `json:"left"` Right RolloutPlan `json:"right"` }
func (RolloutDecisionOR) IsParticipating ¶
func (r RolloutDecisionOR) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)
TODO:SPEC
type RolloutEntries ¶
type RolloutManager ¶
type RolloutManager struct{ Storage Storage }
RolloutManager provides you with feature flag configurability. The manager use storage in a write heavy behavior.
SRP: release manager
func NewRolloutManager ¶
func NewRolloutManager(s Storage) *RolloutManager
func (*RolloutManager) CreateFeatureFlag ¶
func (manager *RolloutManager) CreateFeatureFlag(ctx context.Context, flag *Flag) error
func (*RolloutManager) DeleteFeatureFlag ¶
func (manager *RolloutManager) DeleteFeatureFlag(ctx context.Context, id string) (returnErr error)
TODO: make operation atomic between flags and pilots TODO delete ip addr allows as well TODO: rename
func (*RolloutManager) GetAllReleaseFlagStatesOfThePilot ¶
func (manager *RolloutManager) GetAllReleaseFlagStatesOfThePilot(ctx context.Context, pilotExternalID string, env Environment, flagNames ...string) (map[string]bool, error)
GetAllReleaseFlagStatesOfThePilot check the flag states for every requested release flag. If a flag doesn't exist, then it will provide a turned off state to it. This helps with development where the flag name already agreed and used in the clients but the entity not yet been created in the system. Also this help if a flag is not cleaned up from the clients, the worst thing will be a disabled feature, instead of a breaking client. This also makes it harder to figure out `private` release flags
func (*RolloutManager) ListFeatureFlags ¶
func (manager *RolloutManager) ListFeatureFlags(ctx context.Context) ([]Flag, error)
TODO convert this into a stream
func (*RolloutManager) SetPilotEnrollmentForFeature ¶
func (*RolloutManager) UnsetPilotEnrollmentForFeature ¶
func (*RolloutManager) UpdateFeatureFlag ¶
func (manager *RolloutManager) UpdateFeatureFlag(ctx context.Context, flag *Flag) error
type RolloutPlan ¶
type RolloutPlan interface { IsParticipating(ctx context.Context, pilotExternalID string) (bool, error) Validate() error }
RolloutPlan is the common interface to all rollout type. Rollout expects to determines the behavior of the rollout process. the actual behavior implementation is with the RolloutManager, but the configuration data is located here
type RolloutPlanView ¶
type RolloutPlanView struct {
Plan RolloutPlan `json:"plan"`
}
func (RolloutPlanView) MarshalJSON ¶
func (view RolloutPlanView) MarshalJSON() ([]byte, error)
func (RolloutPlanView) MarshalMapping ¶
func (view RolloutPlanView) MarshalMapping(this RolloutPlan) (map[string]interface{}, error)
func (*RolloutPlanView) UnmarshalJSON ¶
func (view *RolloutPlanView) UnmarshalJSON(bytes []byte) error
func (RolloutPlanView) UnmarshalMapping ¶
func (view RolloutPlanView) UnmarshalMapping(data []byte) (_def RolloutPlan, rErr error)
type RolloutStorage ¶
type Storage ¶
type Storage interface { frameless.OnePhaseCommitProtocol ReleaseFlag(context.Context) FlagStorage ReleasePilot(context.Context) PilotStorage ReleaseRollout(context.Context) RolloutStorage ReleaseEnvironment(context.Context) EnvironmentStorage }