Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take total active users count from adoption freezer endpoint. #223

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ auth/email-link/2:
users: &users
maxReferralsCount: 200
defaultReferralName: bogus
adoptionUrl: https://localhost:3443/v1r/tokenomics-statistics/adoption
kyc:
kyc-step1-reset-url: https://localhost:443/v1w/face-auth/
disableConsumer: false
Expand Down
6 changes: 4 additions & 2 deletions cmd/eskimo-hut/eskimo.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ type (
Offset uint64 `form:"offset" example:"5"`
}
GetUserGrowthArg struct {
TZ string `form:"tz" example:"+4:30"`
Days uint64 `form:"days" example:"7"`
Authorization string `header:"Authorization" swaggerignore:"true" required:"true" example:"some token"`
TZ string `form:"tz" example:"+4:30"`
Days uint64 `form:"days" example:"7"`
}
GetReferralAcquisitionHistoryArg struct {
UserID string `uri:"userId" required:"true" example:"did:ethr:0x4B73C58370AEfcEf86A6021afCDe5673511376B2"`
Expand Down Expand Up @@ -247,6 +248,7 @@ func (s *service) GetUserGrowth( //nolint:gocritic,funlen // False negative.
tz = t.Location()
}
}
ctx = users.ContextWithAuthorization(ctx, req.Data.Authorization) //nolint:revive // .
result, err := s.usersProcessor.GetUserGrowth(ctx, req.Data.Days, tz)
if err != nil {
return nil, server.Unexpected(errors.Wrapf(err, "failed to get user growth stats for: %#v", req.Data))
Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ require (
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.47.0 // indirect
github.com/refraction-networking/utls v1.6.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
Expand All @@ -166,11 +166,11 @@ require (
go.opentelemetry.io/contrib/detectors/gcp v1.30.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
go.opentelemetry.io/otel v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.30.0 // indirect
go.opentelemetry.io/otel v1.31.0 // indirect
go.opentelemetry.io/otel/metric v1.31.0 // indirect
go.opentelemetry.io/otel/sdk v1.31.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
go.opentelemetry.io/otel/trace v1.31.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
Expand Down Expand Up @@ -444,16 +444,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.5
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0/go.mod h1:LqaApwGx/oUmzsbqxkzuBvyoPpkxk3JQWnqfVrJ3wCA=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM=
go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y=
go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
1 change: 1 addition & 0 deletions users/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ type (
}
// | config holds the configuration of this package mounted from `application.yaml`.
config struct {
AdoptionURL string `yaml:"adoptionUrl" mapstructure:"adoptionUrl"`
DefaultReferralName string `yaml:"defaultReferralName"`
messagebroker.Config `mapstructure:",squash"` //nolint:tagliatelle // Nope.
GlobalAggregationInterval struct {
Expand Down
70 changes: 59 additions & 11 deletions users/user_growth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import (
"context"
"fmt"
"math"
"net/http"
"strings"
stdlibtime "time"

"github.com/goccy/go-json"
"github.com/imroc/req/v3"
"github.com/pkg/errors"

messagebroker "github.com/ice-blockchain/wintr/connectors/message_broker"
storage "github.com/ice-blockchain/wintr/connectors/storage/v2"
"github.com/ice-blockchain/wintr/log"
"github.com/ice-blockchain/wintr/time"
)

Expand All @@ -27,8 +30,52 @@ func (r *repository) GetUserGrowth(ctx context.Context, days uint64, tz *stdlibt
if err != nil {
return nil, errors.Wrapf(err, "failed to getGlobalValues for keys:%#v", keys)
}
totalActiveUsers, err := r.getAdoptionTotalActiveUsersValue(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to getAdoptionTotalActiveUsersValue")
}

return r.aggregateGlobalValuesToGrowth(days, now, values, keys, tz), nil
return r.aggregateGlobalValuesToGrowth(days, now, values, keys, tz, totalActiveUsers), nil
}

//nolint:funlen // .
func (r *repository) getAdoptionTotalActiveUsersValue(ctx context.Context) (totalActiveUsers uint64, err error) {
resp, err := req.
SetContext(ctx).
SetRetryCount(25). //nolint:gomnd,mnd // .
SetRetryBackoffInterval(10*stdlibtime.Millisecond, 1*stdlibtime.Second). //nolint:gomnd,mnd // .
SetRetryHook(func(resp *req.Response, err error) {
if err != nil {
log.Error(errors.Wrap(err, "failed to fetch adoption, retrying...")) //nolint:revive // .
} else {
log.Error(errors.Errorf("failed to fetch users adoption with status code:%v, retrying...", resp.GetStatusCode())) //nolint:revive // .
}
}).
SetRetryCondition(func(resp *req.Response, err error) bool {
return err != nil || resp.GetStatusCode() != http.StatusOK
}).
SetHeader("Accept", "application/json").
SetHeader("Accept", "application/json").
SetHeader("Authorization", authorization(ctx)).
SetHeader("Cache-Control", "no-cache, no-store, must-revalidate").
SetHeader("Pragma", "no-cache").
SetHeader("Expires", "0").
Get(r.cfg.AdoptionURL)
if err != nil {
return 0, errors.Wrapf(err, "failed to get fetch `%v`", r.cfg.AdoptionURL)
}
data, err2 := resp.ToBytes()
if err2 != nil {
return 0, errors.Wrapf(err2, "failed to read body of `%v`", r.cfg.AdoptionURL)
}
var adoption struct {
TotalActiveUsers uint64 `json:"totalActiveUsers" example:"11"`
}
if err = json.UnmarshalContext(ctx, data, &adoption); err != nil {
return 0, errors.Wrapf(err, "failed to unmarshal into %#v, data: %v", adoption, string(data))
}

return adoption.TotalActiveUsers, nil
}

func (r *repository) generateUserGrowthKeys(now *time.Time, days uint64) []string {
Expand All @@ -49,11 +96,11 @@ func (r *repository) aggregateGlobalValuesToGrowth(
values []*GlobalUnsigned,
keys []string,
tz *stdlibtime.Location,
totalActiveUsers uint64,
) *UserGrowthStatistics {
nsSinceParentIntervalZeroValue := r.cfg.nanosSinceGlobalAggregationIntervalParentZeroValue(now)
stats := make([]*UserCountTimeSeriesDataPoint, days, days) //nolint:gosimple // .
var activeNow, activeMaxPerParent, dayIdx uint64
nowKey := r.totalActiveUsersGlobalChildKey(now.Time)
var activeMaxPerParent, dayIdx uint64
nowInTZ := time.New(now.In(tz))
for ix, key := range keys {
if ix == 0 {
Expand Down Expand Up @@ -96,13 +143,8 @@ func (r *repository) aggregateGlobalValuesToGrowth(
}
activeMaxPerParent = 0
dayIdx++
} else {
if key == nowKey {
activeNow = val
}
if val > activeMaxPerParent {
activeMaxPerParent = val
}
} else if val > activeMaxPerParent {
activeMaxPerParent = val
}
}
stats[dayIdx-1].UserCount.Active = activeMaxPerParent
Expand All @@ -111,7 +153,7 @@ func (r *repository) aggregateGlobalValuesToGrowth(
return &UserGrowthStatistics{
TimeSeries: stats,
UserCount: UserCount{
Active: activeNow,
Active: totalActiveUsers,
Total: values[0].Value,
},
}
Expand Down Expand Up @@ -307,3 +349,9 @@ func NanosSinceMidnight(now *time.Time) stdlibtime.Duration {
stdlibtime.Duration(now.Minute())*stdlibtime.Minute +
stdlibtime.Duration(now.Hour())*stdlibtime.Hour
}

func authorization(ctx context.Context) (authorization string) {
authorization, _ = ctx.Value(authorizationCtxValueKey).(string) //nolint:errcheck // Not needed.

return
}
Loading