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
84 lines
1.7 KiB
|
2 months ago
|
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)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|