Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
irees committed Nov 3, 2023
1 parent c34e83a commit 5afebdf
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
6 changes: 5 additions & 1 deletion internal/meters/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (m *DefaultMeterProvider) sendMeter(u MeterUser, meterName string, value fl
}
event := defaultMeterEvent{
value: value,
time: time.Now(),
time: time.Now().In(time.UTC),
dims: dims,
}
a[userName] = append(a[userName], event)
Expand All @@ -70,15 +70,19 @@ func (m *DefaultMeterProvider) getValue(u MeterUser, meterName string, startTime
for _, userEvent := range a[u.ID()] {
match := true
if userEvent.time.Equal(endTime) || userEvent.time.After(endTime) {
// fmt.Println("not matched on end time", userEvent.time, endTime)
match = false
}
if userEvent.time.Before(startTime) {
// fmt.Println("not matched on start time", userEvent.time, startTime)
match = false
}
if !matchDims(checkDims, userEvent.dims) {
// fmt.Println("not matched on dims")
match = false
}
if match {
// fmt.Println("matched:", userEvent.value)
total += userEvent.value
}
}
Expand Down
25 changes: 16 additions & 9 deletions internal/meters/limit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ type userMeterLimit struct {
}

type LimitMeterProvider struct {
MeterProvider
UserLimits map[string][]userMeterLimit
MeterProvider
}

func NewLimitMeterProvider(provider MeterProvider) *LimitMeterProvider {
Expand Down Expand Up @@ -57,32 +57,39 @@ func (c *LimitMeter) GetLimit(meterName string, checkDims Dimensions) (time.Time
}
}
if !found {
// fmt.Println("no limit found")
return time.Now(), time.Now(), 0, false
}
now := time.Now()
now := time.Now().In(time.UTC)
d1 := now
d2 := now
if lim.Period == "month" {
d1 = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)
d2 = d1.AddDate(0, 1, 0)
} else if lim.Period == "day" {
if lim.Period == "day" {
d1 = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
d2 = d1.AddDate(0, 0, 1)
} else if lim.Period == "year" {
} else if lim.Period == "month" {
d1 = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)
d2 = d1.AddDate(0, 1, 0)
} else if lim.Period == "year" {
d1 = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, time.UTC)
d2 = d1.AddDate(1, 0, 0)
} else if lim.Period == "total" {
d1 = time.Unix(0, 0)
d2 = time.Unix(1<<63-1, 0)
} else {
return time.Now(), time.Now(), 0, false
return now, now, 0, false
}
// fmt.Println("limit found:", d1, d2, lim.Limit, lim.Period)
return d1, d2, lim.Limit, true
}

func (c *LimitMeter) Meter(meterName string, value float64, extraDimensions Dimensions) error {
d1, d2, lim, foundLimit := c.GetLimit(meterName, extraDimensions)
a, _ := c.ApiMeter.GetValue(meterName, d1, d2, extraDimensions)
a, valueFound := c.GetValue(meterName, d1, d2, extraDimensions)
_ = valueFound
// if !valueFound {
// fmt.Println("value not found")
// }
// fmt.Println("a:", a, "value:", value, "lim:", lim, "extraDims:", extraDimensions)
if foundLimit && a+value > lim {
return errors.New("rate limited")
}
Expand Down
38 changes: 26 additions & 12 deletions internal/meters/limit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,60 @@ func TestLimitMeter(t *testing.T) {
user := testUser{name: "testuser"}
mp := NewDefaultMeterProvider()
cmp := NewLimitMeterProvider(mp)

testLimitMeter(t, cmp, meterName, user)
}

func testLimitMeter(t *testing.T, cmp *LimitMeterProvider, meterName string, user testUser) {
m := cmp.NewMeter(user)
testDims := Dimensions{{Key: "ok", Value: "test"}}
testDims1 := Dimensions{{Key: "ok", Value: "test"}}
testDims2 := Dimensions{{Key: "ok", Value: "bar"}}

lim1 := 100.0
lim2 := 500.0
incr := 15.0

cmp.UserLimits[user.name] = append(cmp.UserLimits[user.name],
userMeterLimit{
MeterName: meterName,
Period: "month",
Limit: 100.0,
Dims: testDims,
Limit: lim1,
Dims: testDims1,
},
userMeterLimit{
MeterName: meterName,
Period: "day",
Limit: 500.0,
Limit: lim2,
Dims: testDims2,
},
)

// 1
successCount1 := 0.0
for i := 0; i < 10; i++ {
err := m.Meter(meterName, 15.0, testDims)
for i := 0; i < 50; i++ {
err := m.Meter(meterName, incr, testDims1)
if err == nil {
successCount1 += 1
}
}
assert.Equal(t, successCount1, math.Floor(100.0/15.0))
assert.Equal(t, successCount1, math.Floor(lim1/incr))

// 2
successCount2 := 0.0
for i := 0; i < 50; i++ {
err := m.Meter(meterName, 15.0, testDims2)
err := m.Meter(meterName, incr, testDims2)
if err == nil {
successCount2 += 1
}
}
assert.Equal(t, successCount2, math.Floor(500.0/15.0))
assert.Equal(t, successCount2, math.Floor(lim2/incr))

v1, _ := m.GetValue(meterName, time.Unix(0, 0), time.Now(), testDims)
assert.Equal(t, successCount1*15.0, v1)
// total 1
v1, _ := m.GetValue(meterName, time.Unix(0, 0), time.Now(), testDims1)
assert.Equal(t, successCount1*incr, v1)

// total 2
v2, _ := m.GetValue(meterName, time.Unix(0, 0), time.Now(), testDims2)
assert.Equal(t, successCount2*15.0, v2)
assert.Equal(t, successCount2*incr, v2)

}

0 comments on commit 5afebdf

Please sign in to comment.