You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
1.7 KiB

package main
import (
"context"
"time"
"tera-clone/services/tera-api/internal/domain"
)
type resetButtonStateReader interface {
ResetButtonPressed(context.Context) (bool, error)
}
type factoryResetStore interface {
FactoryReset(context.Context) (domain.Operation, error)
}
func runFactoryResetButtonMonitor(
ctx context.Context,
reader resetButtonStateReader,
store factoryResetStore,
pollInterval time.Duration,
holdDuration time.Duration,
onReset func(domain.Operation),
onError func(error),
) {
if pollInterval <= 0 {
pollInterval = 100 * time.Millisecond
}
if holdDuration <= 0 {
holdDuration = time.Second
}
ticker := time.NewTicker(pollInterval)
defer ticker.Stop()
var pressedAt time.Time
handled := false
unavailable := false
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
probeContext, cancel := context.WithTimeout(ctx, pollInterval)
pressed, err := reader.ResetButtonPressed(probeContext)
cancel()
if err != nil {
if !unavailable && onError != nil {
onError(err)
}
unavailable = true
pressedAt = time.Time{}
handled = false
continue
}
unavailable = false
if !pressed {
pressedAt = time.Time{}
handled = false
continue
}
if pressedAt.IsZero() {
pressedAt = time.Now()
continue
}
if handled || time.Since(pressedAt) < holdDuration {
continue
}
resetContext, resetCancel := context.WithTimeout(ctx, 15*time.Second)
operation, resetErr := store.FactoryReset(resetContext)
resetCancel()
handled = true
if resetErr != nil {
if onError != nil {
onError(resetErr)
}
continue
}
if onReset != nil {
onReset(operation)
}
}
}
}