Skip to content

Commit

Permalink
Fixed collection of statuses.
Browse files Browse the repository at this point in the history
  • Loading branch information
ptabor committed Dec 7, 2024
1 parent da6e6c1 commit bc2a46e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
2 changes: 1 addition & 1 deletion application/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func (a *Application) Update() error {
if err == nil {
break
}
a.log("error getting receiever status: %v", err)
a.log("error getting receiver status: %v", err)
a.log("unable to get status from device; attempt %d/5, retrying...", i+1)
time.Sleep(time.Second * 2)
}
Expand Down
64 changes: 60 additions & 4 deletions http/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"golang.org/x/sync/errgroup"
"net"
"net/http"
"strconv"
Expand All @@ -22,6 +23,9 @@ type Handler struct {

verbose bool
autoconnect bool
// autoupdatePeriodSec defines how frequently app.Update method is called in the background.
autoupdatePeriod time.Duration
autoupdateTicker *time.Ticker
}

func NewHandler(verbose bool) *Handler {
Expand All @@ -31,6 +35,9 @@ func NewHandler(verbose bool) *Handler {
mux: http.NewServeMux(),
mu: sync.Mutex{},
autoconnect: false,

autoupdatePeriod: time.Duration(-1),
autoupdateTicker: nil,
}
handler.registerHandlers()
return handler
Expand All @@ -44,6 +51,24 @@ func (h *Handler) Autoconnect() error {
return h.connectAllInternal("", "3")
}

// AutoUpdate configures the handler to perform auto-update of all the cast devices & groups.
// It's intended to be called just after `NewHandler()`, before the handler is registered in the server.
// Thanks to AutoUpdate, /status and /statuses returns relatively recent status 'instantly'.
func (h *Handler) AutoUpdate(period time.Duration) error {
// Setting the autoconnect property - to allow (in future) periodic refresh of the connections.
h.autoupdatePeriod = period
h.autoupdateTicker = time.NewTicker(period)
go func() {
for {
<-h.autoupdateTicker.C
if err := h.UpdateAll(); err != nil {
log.Printf("AutoUpdate issued UpdateAll failed: %v", err)
}
}
}()
return nil
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.mux.ServeHTTP(w, r)
}
Expand Down Expand Up @@ -346,7 +371,14 @@ func (h *Handler) status(w http.ResponseWriter, r *http.Request) {
return
}
h.log("status for device")

syncUpdate := r.URL.Query().Get("syncUpdate") == "true"
if syncUpdate {
if err := app.Update(); err != nil {
h.log("error updating status: %v", err)
httpError(w, fmt.Errorf("error updating status: %w", err))
return
}
}
castApplication, castMedia, castVolume := app.Status()
statusResponse := fromApplicationStatus(
castApplication,
Expand All @@ -362,26 +394,50 @@ func (h *Handler) status(w http.ResponseWriter, r *http.Request) {
}
}

func (h *Handler) UpdateAll() error {
uuids := h.ConnectedDeviceUUIDs()
g := new(errgroup.Group)
for _, deviceUUID := range uuids {
app, ok := h.app(deviceUUID)
if ok {
g.Go(func() error { return app.Update() })
}
}
return g.Wait()
}

func (h *Handler) statuses(w http.ResponseWriter, r *http.Request) {
h.log("statuses for devices")
syncUpdate := r.URL.Query().Get("syncUpdate") == "true"
uuids := h.ConnectedDeviceUUIDs()
mapUUID2Ch := map[string]chan statusResponse{}

g := new(errgroup.Group)
for _, deviceUUID := range uuids {
app, ok := h.app(deviceUUID)
if ok {
ch := make(chan statusResponse, 1)
mapUUID2Ch[deviceUUID] = ch
go func() {
g.Go(func() error {
if syncUpdate {
if err := app.Update(); err != nil {
return err
}
}
castApplication, castMedia, castVolume := app.Status()
ch <- fromApplicationStatus(
castApplication,
castMedia,
castVolume,
)
}()
return nil
})
}
}
if err := g.Wait(); err != nil {
h.log("collecting statuses failed: %v", err)
httpError(w, fmt.Errorf("collecting statuses failed: %w", err))
return
}

statusResponses := map[string]statusResponse{}
for deviceUUID, ch := range mapUUID2Ch {
Expand Down

0 comments on commit bc2a46e

Please sign in to comment.