Skip to content

Commit

Permalink
Take total active users count from adoption freezer endpoint. (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-myles authored Oct 13, 2024
1 parent bbd7b3b commit e0bcc41
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 31 deletions.
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
}

0 comments on commit e0bcc41

Please sign in to comment.