feat: Fix Deployment DAUs to work with local timezones (#7647)

* chore: Add timezone param to DAU SQL query
* Merge DAUs response
* Pass time offsets to metricscache
This commit is contained in:
Steven Masley
2023-05-30 19:18:27 +02:00
committed by GitHub
parent 68658b5197
commit c795a0e500
29 changed files with 606 additions and 310 deletions

View File

@ -1720,12 +1720,48 @@ func (c *Client) Experiments(ctx context.Context) (Experiments, error) {
return exp, json.NewDecoder(res.Body).Decode(&exp)
}
type DeploymentDAUsResponse struct {
Entries []DAUEntry `json:"entries"`
type DAUsResponse struct {
Entries []DAUEntry `json:"entries"`
TZHourOffset int `json:"tz_hour_offset"`
}
func (c *Client) DeploymentDAUs(ctx context.Context) (*DeploymentDAUsResponse, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/insights/daus", nil)
type DAUEntry struct {
Date time.Time `json:"date" format:"date-time"`
Amount int `json:"amount"`
}
type DAURequest struct {
TZHourOffset int
}
func (d DAURequest) asRequestOption() RequestOption {
return func(r *http.Request) {
q := r.URL.Query()
q.Set("tz_offset", strconv.Itoa(d.TZHourOffset))
r.URL.RawQuery = q.Encode()
}
}
func TimezoneOffsetHour(loc *time.Location) int {
if loc == nil {
// Default to UTC time to be consistent across all callers.
loc = time.UTC
}
_, offsetSec := time.Now().In(loc).Zone()
// Convert to hours
return offsetSec / 60 / 60
}
func (c *Client) DeploymentDAUsLocalTZ(ctx context.Context) (*DAUsResponse, error) {
return c.DeploymentDAUs(ctx, TimezoneOffsetHour(time.Local))
}
// DeploymentDAUs requires a tzOffset in hours. Use 0 for UTC, and TimezoneOffsetHour(time.Local) for the
// local timezone.
func (c *Client) DeploymentDAUs(ctx context.Context, tzOffset int) (*DAUsResponse, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/insights/daus", nil, DAURequest{
TZHourOffset: tzOffset,
}.asRequestOption())
if err != nil {
return nil, xerrors.Errorf("execute request: %w", err)
}
@ -1735,7 +1771,7 @@ func (c *Client) DeploymentDAUs(ctx context.Context) (*DeploymentDAUsResponse, e
return nil, ReadBodyAsError(res)
}
var resp DeploymentDAUsResponse
var resp DAUsResponse
return &resp, json.NewDecoder(res.Body).Decode(&resp)
}