Files
story/internal/onboarding/close.go
T

49 lines
1.6 KiB
Go
Raw Normal View History

package onboarding
import (
"context"
"errors"
"github.com/jackc/pgx/v5"
"time"
)
func (s *Service) stateAckCanClose(ctx context.Context, tx pgx.Tx, d Device) (bool, error) {
var setupID string
err := tx.QueryRow(ctx, `SELECT id::text FROM device_setup_session WHERE device_id=$1::uuid AND boot_id=$2::uuid AND closed_at IS NULL ORDER BY created_at DESC LIMIT 1`, d.ID, d.BootID).Scan(&setupID)
if errors.Is(err, pgx.ErrNoRows) {
return false, nil
}
if err != nil {
return false, err
}
_, allowed, err := s.closeDelay(ctx, tx, d, setupID)
return allowed, err
}
func (s *Service) closeDelay(ctx context.Context, tx pgx.Tx, d Device, setupID string) (int64, bool, error) {
var saved time.Time
var web *time.Time
err := tx.QueryRow(ctx, `SELECT a.accepted_at,CASE WHEN ss.web_ack_binding_id=b.id AND ss.web_ack_generation=b.generation THEN ss.web_ack_at END FROM device_state_ack a JOIN device_binding b ON b.device_id=a.device_id AND b.generation=a.binding_generation AND b.unbound_at IS NULL JOIN device_setup_session ss ON ss.device_id=b.device_id AND ss.id=$4::uuid WHERE a.device_id=$1::uuid AND a.binding_generation=$2 AND a.boot_id=$3::uuid`, d.ID, d.Generation, d.BootID, setupID).Scan(&saved, &web)
if errors.Is(err, pgx.ErrNoRows) {
return 30000, false, nil
}
if err != nil {
return 0, false, err
}
deadline := saved.Add(30 * time.Second)
if web != nil {
both := saved
if web.After(both) {
both = *web
}
if short := both.Add(3 * time.Second); short.Before(deadline) {
deadline = short
}
}
delay := deadline.Sub(s.now()).Milliseconds()
if delay < 0 {
delay = 0
}
return delay, delay == 0, nil
}