Documentation
¶
Index ¶
- Constants
- func SortedPeriodsFromDedupedTimes(ts []time.Time) []recurrence.Period
- type BalanceConnector
- type BalanceHistoryParams
- type BalanceSnapshotConnector
- 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 BalanceSnapshotConnector, ownerConnector OwnerConnector, streamingConnector streaming.Connector, logger *slog.Logger, ) BalanceConnector
type BalanceSnapshotConnector ¶
type BalanceSnapshotConnector 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[BalanceSnapshotConnector] }
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 BalanceSnapshotConnector, 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) //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 }
type OwnerNotFoundError ¶
type OwnerNotFoundError struct { Owner NamespacedGrantOwner AttemptedOwner string }
func (OwnerNotFoundError) Error ¶
func (e OwnerNotFoundError) Error() string