mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
perf: project quotas and usages (#6441)
* project quota added * project quota removed * add periods table * make log record generic * accumulate usage * query usage * count action run seconds * fix filter in ReportQuotaUsage * fix existing tests * fix logstore tests * fix typo * fix: add quota unit tests command side * fix: add quota unit tests command side * fix: add quota unit tests command side * move notifications into debouncer and improve limit querying * cleanup * comment * fix: add quota unit tests command side * fix remaining quota usage query * implement InmemLogStorage * cleanup and linting * improve test * fix: add quota unit tests command side * fix: add quota unit tests command side * fix: add quota unit tests command side * fix: add quota unit tests command side * action notifications and fixes for notifications query * revert console prefix * fix: add quota unit tests command side * fix: add quota integration tests * improve accountable requests * improve accountable requests * fix: add quota integration tests * fix: add quota integration tests * fix: add quota integration tests * comment * remove ability to store logs in db and other changes requested from review * changes requested from review * changes requested from review * Update internal/api/http/middleware/access_interceptor.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * tests: fix quotas integration tests * improve incrementUsageStatement * linting * fix: delete e2e tests as intergation tests cover functionality * Update internal/api/http/middleware/access_interceptor.go Co-authored-by: Silvan <silvan.reusser@gmail.com> * backup * fix conflict * create rc * create prerelease * remove issue release labeling * fix tracing --------- Co-authored-by: Livio Spring <livio.a@gmail.com> Co-authored-by: Stefan Benz <stefan@caos.ch> Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
This commit is contained in:
@@ -14,9 +14,8 @@ import (
|
||||
"github.com/benbjohnson/clock"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/logstore"
|
||||
emittermock "github.com/zitadel/zitadel/internal/logstore/emitters/mock"
|
||||
quotaqueriermock "github.com/zitadel/zitadel/internal/logstore/quotaqueriers/mock"
|
||||
"github.com/zitadel/zitadel/internal/repository/quota"
|
||||
emittermock "github.com/zitadel/zitadel/internal/logstore/mock"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,7 +26,7 @@ const (
|
||||
type args struct {
|
||||
mainSink *logstore.EmitterConfig
|
||||
secondarySink *logstore.EmitterConfig
|
||||
config quota.AddedEvent
|
||||
config *query.Quota
|
||||
}
|
||||
|
||||
type want struct {
|
||||
@@ -137,28 +136,6 @@ func TestService(t *testing.T) {
|
||||
len: 0,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "cleanupping works",
|
||||
args: args{
|
||||
mainSink: emitterConfig(withCleanupping(17*time.Second, 28*time.Second)),
|
||||
secondarySink: emitterConfig(withDebouncerConfig(&logstore.DebouncerConfig{
|
||||
MinFrequency: 0,
|
||||
MaxBulkSize: 15,
|
||||
}), withCleanupping(5*time.Second, 47*time.Second)),
|
||||
config: quotaConfig(),
|
||||
},
|
||||
want: want{
|
||||
enabled: true,
|
||||
remaining: nil,
|
||||
mainSink: wantSink{
|
||||
bulks: repeat(1, 60),
|
||||
len: 21,
|
||||
},
|
||||
secondarySink: wantSink{
|
||||
bulks: repeat(15, 4),
|
||||
len: 18,
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "when quota has a limit of 90, 30 are remaining",
|
||||
args: args{
|
||||
@@ -232,27 +209,24 @@ func runTest(t *testing.T, name string, args args, want want) bool {
|
||||
})
|
||||
}
|
||||
|
||||
func given(t *testing.T, args args, want want) (context.Context, *clock.Mock, *emittermock.InmemLogStorage, *emittermock.InmemLogStorage, *logstore.Service) {
|
||||
func given(t *testing.T, args args, want want) (context.Context, *clock.Mock, *emittermock.InmemLogStorage, *emittermock.InmemLogStorage, *logstore.Service[*emittermock.Record]) {
|
||||
ctx := context.Background()
|
||||
clock := clock.NewMock()
|
||||
|
||||
periodStart := time.Time{}
|
||||
clock.Set(args.config.From)
|
||||
|
||||
mainStorage := emittermock.NewInMemoryStorage(clock)
|
||||
mainEmitter, err := logstore.NewEmitter(ctx, clock, args.mainSink, mainStorage)
|
||||
mainStorage := emittermock.NewInMemoryStorage(clock, args.config)
|
||||
mainEmitter, err := logstore.NewEmitter[*emittermock.Record](ctx, clock, args.mainSink, mainStorage)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error but got %v", err)
|
||||
}
|
||||
secondaryStorage := emittermock.NewInMemoryStorage(clock)
|
||||
secondaryEmitter, err := logstore.NewEmitter(ctx, clock, args.secondarySink, secondaryStorage)
|
||||
secondaryStorage := emittermock.NewInMemoryStorage(clock, args.config)
|
||||
secondaryEmitter, err := logstore.NewEmitter[*emittermock.Record](ctx, clock, args.secondarySink, secondaryStorage)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error but got %v", err)
|
||||
}
|
||||
|
||||
svc := logstore.New(
|
||||
quotaqueriermock.NewNoopQuerier(&args.config, periodStart),
|
||||
logstore.UsageReporterFunc(func(context.Context, []*quota.NotificationDueEvent) error { return nil }),
|
||||
svc := logstore.New[*emittermock.Record](
|
||||
mainStorage,
|
||||
mainEmitter,
|
||||
secondaryEmitter)
|
||||
|
||||
@@ -262,7 +236,7 @@ func given(t *testing.T, args args, want want) (context.Context, *clock.Mock, *e
|
||||
return ctx, clock, mainStorage, secondaryStorage, svc
|
||||
}
|
||||
|
||||
func when(svc *logstore.Service, ctx context.Context, clock *clock.Mock) *uint64 {
|
||||
func when(svc *logstore.Service[*emittermock.Record], ctx context.Context, clock *clock.Mock) *uint64 {
|
||||
var remaining *uint64
|
||||
for i := 0; i < ticks; i++ {
|
||||
svc.Handle(ctx, emittermock.NewRecord(clock))
|
||||
|
Reference in New Issue
Block a user