Documentation
¶
Index ¶
- Constants
- func SortedPeriodsFromDedupedTimes(ts []time.Time) []recurrence.Period
- type BalanceConnector
- type BalanceHistoryParams
- type BalanceSnapshotRepo
- type CreateGrantInput
- type EndCurrentUsagePeriodParams
- type Engine
- type ExpirationPeriod
- type ExpirationPeriodDuration
- type Grant
- func (g Grant) ActiveAt(t time.Time) bool
- func (g Grant) GetExpiration() time.Time
- func (g Grant) GetNamespacedID() models.NamespacedID
- func (g Grant) GetNamespacedOwner() NamespacedGrantOwner
- func (g Grant) RecurrenceBalance(currentBalance float64) float64
- func (g Grant) RolloverBalance(currentBalance float64) float64
- type GrantBalanceMap
- func (g GrantBalanceMap) Balance() float64
- func (g GrantBalanceMap) Burn(grantID string, amount float64)
- func (g GrantBalanceMap) Copy() GrantBalanceMap
- func (g GrantBalanceMap) ExactlyForGrants(grants []Grant) bool
- func (g GrantBalanceMap) OverrideWith(gbm GrantBalanceMap)
- func (g GrantBalanceMap) Set(grantID string, amount float64)
- type GrantBalanceNoSavedBalanceForOwnerError
- type GrantBalanceSnapshot
- type GrantBurnDownHistory
- type GrantBurnDownHistorySegment
- type GrantConnector
- type GrantNotFoundError
- type GrantOrderBy
- type GrantOwner
- type GrantRepo
- type GrantRepoCreateGrantInput
- type GrantUsage
- type GrantUsageTerminationReason
- type ListGrantsParams
- type NamespacedGrantOwner
- type OwnerConnector
- type OwnerMeter
- type OwnerNotFoundError
- type Pagination
- type QueryUsageFn
- type ResetUsageForOwnerParams
- type SegmentTerminationReason
Constants ¶
const (
GrantPriorityDefault uint8 = 1
)
Variables ¶
This section is empty.
Functions ¶
func SortedPeriodsFromDedupedTimes ¶
func SortedPeriodsFromDedupedTimes(ts []time.Time) []recurrence.Period
Returns a list of non-overlapping periods between the sorted times.
Types ¶
type BalanceConnector ¶
type BalanceConnector interface {
GetBalanceOfOwner(ctx context.Context, owner NamespacedGrantOwner, at time.Time) (*GrantBalanceSnapshot, error)
GetBalanceHistoryOfOwner(ctx context.Context, owner NamespacedGrantOwner, params BalanceHistoryParams) (GrantBurnDownHistory, error)
ResetUsageForOwner(ctx context.Context, owner NamespacedGrantOwner, params ResetUsageForOwnerParams) (balanceAfterReset *GrantBalanceSnapshot, err error)
}
Generic connector for balance related operations.
func NewBalanceConnector ¶
func NewBalanceConnector( grantRepo GrantRepo, balanceSnapshotConnector BalanceSnapshotRepo, ownerConnector OwnerConnector, streamingConnector streaming.Connector, logger *slog.Logger, ) BalanceConnector
type BalanceSnapshotRepo ¶
type BalanceSnapshotRepo interface {
InvalidateAfter(ctx context.Context, owner NamespacedGrantOwner, at time.Time) error
GetLatestValidAt(ctx context.Context, owner NamespacedGrantOwner, at time.Time) (GrantBalanceSnapshot, error)
Save(ctx context.Context, owner NamespacedGrantOwner, balances []GrantBalanceSnapshot) error
entutils.TxCreator
entutils.TxUser[BalanceSnapshotRepo]
}
type CreateGrantInput ¶
type CreateGrantInput struct {
Amount float64
Priority uint8
EffectiveAt time.Time
Expiration ExpirationPeriod
Metadata map[string]string
ResetMaxRollover float64
ResetMinRollover float64
Recurrence *recurrence.Recurrence
}
type Engine ¶
type Engine interface {
Run(ctx context.Context, grants []Grant, startingBalances GrantBalanceMap, startingOverage float64, period recurrence.Period) (endingBalances GrantBalanceMap, endingOverage float64, history []GrantBurnDownHistorySegment, err error)
}
func NewEngine ¶
func NewEngine(getFeatureUsage QueryUsageFn, granuality models.WindowSize) Engine
type ExpirationPeriod ¶
type ExpirationPeriod struct {
// Count The expiration period count like 12 months.
Count uint8 `json:"count,omitempty"`
// Duration The expiration period duration like month.
Duration ExpirationPeriodDuration `json:"duration,omitempty"`
}
ExpirationPeriod of a credit grant.
func (ExpirationPeriod) GetExpiration ¶
func (c ExpirationPeriod) GetExpiration(t time.Time) time.Time
type ExpirationPeriodDuration ¶
type ExpirationPeriodDuration string
const ( ExpirationPeriodDurationHour ExpirationPeriodDuration = "HOUR" ExpirationPeriodDurationDay ExpirationPeriodDuration = "DAY" ExpirationPeriodDurationWeek ExpirationPeriodDuration = "WEEK" ExpirationPeriodDurationMonth ExpirationPeriodDuration = "MONTH" ExpirationPeriodDurationYear ExpirationPeriodDuration = "YEAR" )
Defines values for ExpirationPeriodDuration.
func (ExpirationPeriodDuration) Values ¶
func (ExpirationPeriodDuration) Values() (kinds []string)
type Grant ¶
type Grant struct {
models.ManagedModel
models.NamespacedModel
// ID is the readonly identifies of a grant.
ID string `json:"id,omitempty"`
// Generic Owner reference
OwnerID GrantOwner `json:"owner"`
// Amount The amount to grant. Can be positive or negative number.
Amount float64 `json:"amount"`
// Priority is a positive decimal numbers. With lower numbers indicating higher importance;
// for example, a priority of 1 is more urgent than a priority of 2.
// When there are several credit grants available for a single invoice, the system selects the credit with the highest priority.
// In cases where credit grants share the same priority level, the grant closest to its expiration will be used first.
// In the case of two credits have identical priorities and expiration dates, the system will use the credit that was created first.
Priority uint8 `json:"priority"`
// EffectiveAt The effective date.
EffectiveAt time.Time `json:"effectiveAt"`
// Expiration The expiration configuration.
Expiration ExpirationPeriod `json:"expiration"`
// ExpiresAt contains the exact expiration date calculated from effectiveAt and Expiration for rendering.
// ExpiresAt is exclusive, meaning that the grant is no longer active after this time, but it is still active at the time.
ExpiresAt time.Time `json:"expiresAt"`
Metadata map[string]string `json:"metadata,omitempty"`
// For user initiated voiding of the grant.
VoidedAt *time.Time `json:"voidedAt,omitempty"`
// How much of the grant can be rolled over after a reset operation.
// Balance after a reset will be between ResetMinRollover and ResetMaxRollover.
ResetMaxRollover float64 `json:"resetMaxRollover"`
// How much balance the grant must have after a reset.
// Balance after a reset will be between ResetMinRollover and ResetMaxRollover.
ResetMinRollover float64 `json:"resetMinRollover"`
// Recurrence config for the grant. If nil the grant doesn't recur.
Recurrence *recurrence.Recurrence `json:"recurrence,omitempty"`
}
Grant is an immutable definition used to increase balance.
func (Grant) GetExpiration ¶
Calculates expiration from effectiveAt and Expiration.
func (Grant) GetNamespacedID ¶
func (g Grant) GetNamespacedID() models.NamespacedID
func (Grant) GetNamespacedOwner ¶
func (g Grant) GetNamespacedOwner() NamespacedGrantOwner
func (Grant) RecurrenceBalance ¶
Calculates the new balance after a recurrence from the current balance
func (Grant) RolloverBalance ¶
Calculates the new balance after a rollover from the current balance
type GrantBalanceMap ¶
Represents a point in time balance of grants
func (GrantBalanceMap) Balance ¶
func (g GrantBalanceMap) Balance() float64
returns the combined balance of all grants
func (GrantBalanceMap) Burn ¶
func (g GrantBalanceMap) Burn(grantID string, amount float64)
func (GrantBalanceMap) Copy ¶
func (g GrantBalanceMap) Copy() GrantBalanceMap
func (GrantBalanceMap) ExactlyForGrants ¶
func (g GrantBalanceMap) ExactlyForGrants(grants []Grant) bool
Whether the contents of the GrantBalanceMap exactly matches the list of provided grants. Return false if it has additional grants or if it misses any grants
func (GrantBalanceMap) OverrideWith ¶
func (g GrantBalanceMap) OverrideWith(gbm GrantBalanceMap)
func (GrantBalanceMap) Set ¶
func (g GrantBalanceMap) Set(grantID string, amount float64)
type GrantBalanceNoSavedBalanceForOwnerError ¶
type GrantBalanceNoSavedBalanceForOwnerError struct {
Owner NamespacedGrantOwner
Time time.Time
}
No balance has been saved since start of measurement for the owner
func (GrantBalanceNoSavedBalanceForOwnerError) Error ¶
func (e GrantBalanceNoSavedBalanceForOwnerError) Error() string
type GrantBalanceSnapshot ¶
type GrantBalanceSnapshot struct {
Balances GrantBalanceMap
Overage float64
At time.Time
}
func (GrantBalanceSnapshot) Balance ¶
func (g GrantBalanceSnapshot) Balance() float64
type GrantBurnDownHistory ¶
type GrantBurnDownHistory struct {
// contains filtered or unexported fields
}
func NewGrantBurnDownHistory ¶
func NewGrantBurnDownHistory(segments []GrantBurnDownHistorySegment) (*GrantBurnDownHistory, error)
func (*GrantBurnDownHistory) Overage ¶
func (g *GrantBurnDownHistory) Overage() float64
func (*GrantBurnDownHistory) Segments ¶
func (g *GrantBurnDownHistory) Segments() []GrantBurnDownHistorySegment
func (*GrantBurnDownHistory) TotalUsage ¶
func (g *GrantBurnDownHistory) TotalUsage() float64
type GrantBurnDownHistorySegment ¶
type GrantBurnDownHistorySegment struct {
recurrence.Period
BalanceAtStart GrantBalanceMap
TerminationReasons SegmentTerminationReason // Reason why the segment was terminated (could be multiple taking effect at same time)
TotalUsage float64 // Total usage of the feature in the Period
OverageAtStart float64 // Usage beyond what could be burnt down from the grants in the previous segment (if any)
Overage float64 // Usage beyond what cloud be burnt down from the grants
GrantUsages []GrantUsage // Grant usages in the segment order by grant priority
}
GrantBurnDownHistorySegment represents the smallest segment of grant usage which we store and calculate.
A segment represents a period of time in which: 1) The grant priority does not change 2) Grants do not recurr 3) There was no usage reset
It is not necessarily the largest such segment.
func (GrantBurnDownHistorySegment) ApplyUsage ¶
func (s GrantBurnDownHistorySegment) ApplyUsage() GrantBalanceMap
Returns GrantBalanceMap at the end of the segment
func (*GrantBurnDownHistorySegment) ToSnapshot ¶
func (s *GrantBurnDownHistorySegment) ToSnapshot() GrantBalanceSnapshot
Creates a GrantBalanceSnapshot from the starting state of the segment
type GrantConnector ¶
type GrantConnector interface {
CreateGrant(ctx context.Context, owner NamespacedGrantOwner, grant CreateGrantInput) (*Grant, error)
VoidGrant(ctx context.Context, grantID models.NamespacedID) error
ListGrants(ctx context.Context, params ListGrantsParams) ([]Grant, error)
ListActiveGrantsBetween(ctx context.Context, owner NamespacedGrantOwner, from, to time.Time) ([]Grant, error)
GetGrant(ctx context.Context, grantID models.NamespacedID) (Grant, error)
}
func NewGrantConnector ¶
func NewGrantConnector( ownerConnector OwnerConnector, grantRepo GrantRepo, balanceSnapshotConnector BalanceSnapshotRepo, granularity time.Duration, ) GrantConnector
type GrantNotFoundError ¶
type GrantNotFoundError struct {
GrantID string
}
func (*GrantNotFoundError) Error ¶
func (e *GrantNotFoundError) Error() string
type GrantOrderBy ¶
type GrantOrderBy string
const ( GrantOrderByCreatedAt GrantOrderBy = "created_at" GrantOrderByUpdatedAt GrantOrderBy = "updated_at" GrantOrderByExpiresAt GrantOrderBy = "expires_at" GrantOrderByEffectiveAt GrantOrderBy = "effective_at" GrantOrderByOwner GrantOrderBy = "owner_id" // check )
type GrantOwner ¶
type GrantOwner string
type GrantRepo ¶
type GrantRepo interface {
CreateGrant(ctx context.Context, grant GrantRepoCreateGrantInput) (*Grant, error)
VoidGrant(ctx context.Context, grantID models.NamespacedID, at time.Time) error
ListGrants(ctx context.Context, params ListGrantsParams) ([]Grant, error)
// ListActiveGrantsBetween returns all grants that are active at any point between the given time range.
ListActiveGrantsBetween(ctx context.Context, owner NamespacedGrantOwner, from, to time.Time) ([]Grant, error)
GetGrant(ctx context.Context, grantID models.NamespacedID) (Grant, error)
entutils.TxCreator
entutils.TxUser[GrantRepo]
}
type GrantRepoCreateGrantInput ¶
type GrantRepoCreateGrantInput struct {
OwnerID GrantOwner
Namespace string
Amount float64
Priority uint8
EffectiveAt time.Time
Expiration ExpirationPeriod
ExpiresAt time.Time
Metadata map[string]string
ResetMaxRollover float64
ResetMinRollover float64
Recurrence *recurrence.Recurrence
}
type GrantUsage ¶
type GrantUsage struct {
GrantID string
Usage float64
TerminationReason GrantUsageTerminationReason
}
type GrantUsageTerminationReason ¶
type GrantUsageTerminationReason string
const ( GrantUsageTerminationReasonExhausted GrantUsageTerminationReason = "GRANT_EXHAUSTED" // Grant has been fully used GrantUsageTerminationReasonSegmentTermination GrantUsageTerminationReason = "SEGMENT_TERMINATION" // Segment has been terminated )
func (GrantUsageTerminationReason) IsValid ¶
func (GrantUsageTerminationReason) IsValid(reason GrantUsageTerminationReason) bool
type ListGrantsParams ¶
type ListGrantsParams struct {
Namespace string
OwnerID *GrantOwner
IncludeDeleted bool
Offset int
Limit int
OrderBy GrantOrderBy
}
type NamespacedGrantOwner ¶
type NamespacedGrantOwner struct {
Namespace string
ID GrantOwner
}
func (NamespacedGrantOwner) NamespacedID ¶
func (n NamespacedGrantOwner) NamespacedID() models.NamespacedID
Casts the NamespacedGrantOwner to a NamespacedID. Owner might not be a valid ID.
type OwnerConnector ¶
type OwnerConnector interface {
GetMeter(ctx context.Context, owner NamespacedGrantOwner) (*OwnerMeter, error)
GetStartOfMeasurement(ctx context.Context, owner NamespacedGrantOwner) (time.Time, error)
GetPeriodStartTimesBetween(ctx context.Context, owner NamespacedGrantOwner, from, to time.Time) ([]time.Time, error)
GetUsagePeriodStartAt(ctx context.Context, owner NamespacedGrantOwner, at time.Time) (time.Time, error)
GetOwnerSubjectKey(ctx context.Context, owner NamespacedGrantOwner) (string, error)
//FIXME: this is a terrible hack
EndCurrentUsagePeriodTx(ctx context.Context, tx *entutils.TxDriver, owner NamespacedGrantOwner, params EndCurrentUsagePeriodParams) error
//FIXME: this is a terrible hack
LockOwnerForTx(ctx context.Context, tx *entutils.TxDriver, owner NamespacedGrantOwner) error
}
type OwnerMeter ¶
type OwnerMeter struct {
MeterSlug string
DefaultParams *streaming.QueryParams
WindowSize models.WindowSize
SubjectKey string
}
type OwnerNotFoundError ¶
type OwnerNotFoundError struct {
Owner NamespacedGrantOwner
AttemptedOwner string
}
func (OwnerNotFoundError) Error ¶
func (e OwnerNotFoundError) Error() string