Add a device grace period so that it gets notified but not removed

This commit is contained in:
Andre Medeiros 2022-03-26 12:48:51 -04:00
parent 9cc60972dc
commit e5670c9828
4 changed files with 24 additions and 17 deletions

View file

@ -29,6 +29,7 @@ func (a *api) upsertDeviceHandler(w http.ResponseWriter, r *http.Request) {
} }
d.ActiveUntil = time.Now().Unix() + domain.DeviceGracePeriodDuration d.ActiveUntil = time.Now().Unix() + domain.DeviceGracePeriodDuration
d.GracePeriodUntil = d.ActiveUntil + domain.DeviceGracePeriodAfterReceiptExpiry
if err := a.deviceRepo.CreateOrUpdate(ctx, d); err != nil { if err := a.deviceRepo.CreateOrUpdate(ctx, d); err != nil {
a.errorResponse(w, r, 500, err.Error()) a.errorResponse(w, r, 500, err.Error())

View file

@ -52,6 +52,7 @@ func (a *api) checkReceiptHandler(w http.ResponseWriter, r *http.Request) {
_ = a.deviceRepo.Delete(ctx, apns) _ = a.deviceRepo.Delete(ctx, apns)
} else { } else {
dev.ActiveUntil = time.Now().Unix() + domain.DeviceActiveAfterReceitCheckDuration dev.ActiveUntil = time.Now().Unix() + domain.DeviceActiveAfterReceitCheckDuration
dev.GracePeriodUntil = dev.ActiveUntil + domain.DeviceGracePeriodAfterReceiptExpiry
_ = a.deviceRepo.Update(ctx, &dev) _ = a.deviceRepo.Update(ctx, &dev)
} }
} }

View file

@ -9,6 +9,7 @@ import (
const ( const (
DeviceGracePeriodDuration = 3600 // 1 hour DeviceGracePeriodDuration = 3600 // 1 hour
DeviceActiveAfterReceitCheckDuration = 3600 * 24 * 30 // ~1 month DeviceActiveAfterReceitCheckDuration = 3600 * 24 * 30 // ~1 month
DeviceGracePeriodAfterReceiptExpiry = 3600 * 24 * 30 // ~1 month
) )
type Device struct { type Device struct {
@ -16,6 +17,7 @@ type Device struct {
APNSToken string APNSToken string
Sandbox bool Sandbox bool
ActiveUntil int64 ActiveUntil int64
GracePeriodUntil int64
} }
func (dev *Device) Validate() error { func (dev *Device) Validate() error {

View file

@ -32,6 +32,7 @@ func (p *postgresDeviceRepository) fetch(ctx context.Context, query string, args
&dev.APNSToken, &dev.APNSToken,
&dev.Sandbox, &dev.Sandbox,
&dev.ActiveUntil, &dev.ActiveUntil,
&dev.GracePeriodUntil,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
@ -42,7 +43,7 @@ func (p *postgresDeviceRepository) fetch(ctx context.Context, query string, args
func (p *postgresDeviceRepository) GetByID(ctx context.Context, id int64) (domain.Device, error) { func (p *postgresDeviceRepository) GetByID(ctx context.Context, id int64) (domain.Device, error) {
query := ` query := `
SELECT id, apns_token, sandbox, active_until SELECT id, apns_token, sandbox, active_until, grace_period_until
FROM devices FROM devices
WHERE id = $1` WHERE id = $1`
@ -59,7 +60,7 @@ func (p *postgresDeviceRepository) GetByID(ctx context.Context, id int64) (domai
func (p *postgresDeviceRepository) GetByAPNSToken(ctx context.Context, token string) (domain.Device, error) { func (p *postgresDeviceRepository) GetByAPNSToken(ctx context.Context, token string) (domain.Device, error) {
query := ` query := `
SELECT id, apns_token, sandbox, active_until SELECT id, apns_token, sandbox, active_until, grace_period_until
FROM devices FROM devices
WHERE apns_token = $1` WHERE apns_token = $1`
@ -76,7 +77,7 @@ func (p *postgresDeviceRepository) GetByAPNSToken(ctx context.Context, token str
func (p *postgresDeviceRepository) GetByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { func (p *postgresDeviceRepository) GetByAccountID(ctx context.Context, id int64) ([]domain.Device, error) {
query := ` query := `
SELECT devices.id, apns_token, sandbox, active_until SELECT devices.id, apns_token, sandbox, active_until, grace_period_until
FROM devices FROM devices
INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id
WHERE devices_accounts.account_id = $1` WHERE devices_accounts.account_id = $1`
@ -86,7 +87,7 @@ func (p *postgresDeviceRepository) GetByAccountID(ctx context.Context, id int64)
func (p *postgresDeviceRepository) GetInboxNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { func (p *postgresDeviceRepository) GetInboxNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) {
query := ` query := `
SELECT devices.id, apns_token, sandbox, active_until SELECT devices.id, apns_token, sandbox, active_until, grace_period_until
FROM devices FROM devices
INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id
WHERE devices_accounts.account_id = $1 AND devices_accounts.inbox_notifiable = TRUE` WHERE devices_accounts.account_id = $1 AND devices_accounts.inbox_notifiable = TRUE`
@ -96,7 +97,7 @@ func (p *postgresDeviceRepository) GetInboxNotifiableByAccountID(ctx context.Con
func (p *postgresDeviceRepository) GetWatcherNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) { func (p *postgresDeviceRepository) GetWatcherNotifiableByAccountID(ctx context.Context, id int64) ([]domain.Device, error) {
query := ` query := `
SELECT devices.id, apns_token, sandbox, active_until SELECT devices.id, apns_token, sandbox, active_until, grace_period_until
FROM devices FROM devices
INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id INNER JOIN devices_accounts ON devices.id = devices_accounts.device_id
WHERE devices_accounts.account_id = $1 AND devices_accounts.watcher_notifiable = TRUE` WHERE devices_accounts.account_id = $1 AND devices_accounts.watcher_notifiable = TRUE`
@ -106,10 +107,10 @@ func (p *postgresDeviceRepository) GetWatcherNotifiableByAccountID(ctx context.C
func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *domain.Device) error { func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *domain.Device) error {
query := ` query := `
INSERT INTO devices (apns_token, sandbox, active_until) INSERT INTO devices (apns_token, sandbox, active_until, grace_period_until)
VALUES ($1, $2, $3) VALUES ($1, $2, $3, $4)
ON CONFLICT(apns_token) DO ON CONFLICT(apns_token) DO
UPDATE SET active_until = $3 UPDATE SET active_until = $3, grace_period_until = $4
RETURNING id` RETURNING id`
return p.pool.QueryRow( return p.pool.QueryRow(
@ -118,6 +119,7 @@ func (p *postgresDeviceRepository) CreateOrUpdate(ctx context.Context, dev *doma
dev.APNSToken, dev.APNSToken,
dev.Sandbox, dev.Sandbox,
dev.ActiveUntil, dev.ActiveUntil,
dev.GracePeriodUntil,
).Scan(&dev.ID) ).Scan(&dev.ID)
} }
@ -128,8 +130,8 @@ func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Devic
query := ` query := `
INSERT INTO devices INSERT INTO devices
(apns_token, sandbox, active_until) (apns_token, sandbox, active_until, grace_period_until)
VALUES ($1, $2, $3) VALUES ($1, $2, $3, $4)
RETURNING id` RETURNING id`
return p.pool.QueryRow( return p.pool.QueryRow(
@ -138,6 +140,7 @@ func (p *postgresDeviceRepository) Create(ctx context.Context, dev *domain.Devic
dev.APNSToken, dev.APNSToken,
dev.Sandbox, dev.Sandbox,
dev.ActiveUntil, dev.ActiveUntil,
dev.GracePeriodUntil,
).Scan(&dev.ID) ).Scan(&dev.ID)
} }
@ -148,10 +151,10 @@ func (p *postgresDeviceRepository) Update(ctx context.Context, dev *domain.Devic
query := ` query := `
UPDATE devices UPDATE devices
SET active_until = $2 SET active_until = $2, grace_period_until = $3
WHERE id = $1` WHERE id = $1`
res, err := p.pool.Exec(ctx, query, dev.ID, dev.ActiveUntil) res, err := p.pool.Exec(ctx, query, dev.ID, dev.ActiveUntil, dev.GracePeriodUntil)
if res.RowsAffected() != 1 { if res.RowsAffected() != 1 {
return fmt.Errorf("weird behaviour, total rows affected: %d", res.RowsAffected()) return fmt.Errorf("weird behaviour, total rows affected: %d", res.RowsAffected())
@ -211,7 +214,7 @@ func (p *postgresDeviceRepository) GetNotifiable(ctx context.Context, dev *domai
} }
func (p *postgresDeviceRepository) PruneStale(ctx context.Context, before int64) (int64, error) { func (p *postgresDeviceRepository) PruneStale(ctx context.Context, before int64) (int64, error) {
query := `DELETE FROM devices WHERE active_until < $1` query := `DELETE FROM devices WHERE grace_period_until < $1`
res, err := p.pool.Exec(ctx, query, before) res, err := p.pool.Exec(ctx, query, before)