release

package
v0.0.0-...-4e1183a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2021 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
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`
)
View Source
const (
	ErrEnvironmentNameIsEmpty frameless.Error = `deployment environment name can't be empty`
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Environment

type Environment struct {
	ID   string `ext:"ID" json:"id"`
	Name string `json:"name"`
}

func (Environment) Validate

func (env Environment) Validate() error

type Flag

type Flag struct {
	ID   string `ext:"ID" json:"id,omitempty"`
	Name string `json:"name"`
}

Flag is the basic entity with properties that feature flag holds

func (Flag) Validate

func (f Flag) Validate() error

type FlagEntries

type FlagEntries = iterators.Interface

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 PilotEntries = iterators.Interface

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.

func (PseudoRandPercentageAlgorithms) FNV1a64

func (g PseudoRandPercentageAlgorithms) FNV1a64(id string, seedSalt int64) (int, error)

FNV1a64 implements pseudo random percentage calculation with FNV-1a64.

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 (r Rollout) MarshalJSON() ([]byte, error)

func (*Rollout) UnmarshalJSON

func (r *Rollout) UnmarshalJSON(bs []byte) error

func (Rollout) Validate

func (r Rollout) Validate() error

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

func (RolloutDecisionAND) Validate

func (r RolloutDecisionAND) Validate() 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 (s RolloutDecisionByAPI) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)

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 (r RolloutDecisionByGlobal) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)

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 (s RolloutDecisionByPercentage) IsParticipating(ctx context.Context, pilotExternalID string) (bool, error)

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

func (RolloutDecisionNOT) Validate

func (r RolloutDecisionNOT) Validate() 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

func (RolloutDecisionOR) Validate

func (r RolloutDecisionOR) Validate() error

TODO:SPEC

type RolloutEntries

type RolloutEntries = iterators.Interface

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 (manager *RolloutManager) SetPilotEnrollmentForFeature(ctx context.Context, flagID string, envID string, externalPilotID string, isParticipating bool) error

func (*RolloutManager) UnsetPilotEnrollmentForFeature

func (manager *RolloutManager) UnsetPilotEnrollmentForFeature(ctx context.Context, flagID string, envID string, pilotExternalID string) error

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 Storage

type Storage interface {
	frameless.OnePhaseCommitProtocol
	ReleaseFlag(context.Context) FlagStorage
	ReleasePilot(context.Context) PilotStorage
	ReleaseRollout(context.Context) RolloutStorage
	ReleaseEnvironment(context.Context) EnvironmentStorage
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL