diff --git a/web/handlers/admin/dashboard.go b/web/handlers/admin/dashboard.go index 352ff15..d891eb7 100644 --- a/web/handlers/admin/dashboard.go +++ b/web/handlers/admin/dashboard.go @@ -5,8 +5,11 @@ package admin import ( "fmt" "net/http" + "time" "go.mindeco.de/http/render" + "go.mindeco.de/log/level" + "go.mindeco.de/logging" refs "go.mindeco.de/ssb-refs" "github.com/ssb-ngi-pointer/go-ssb-room/internal/network" @@ -25,36 +28,53 @@ type dashboardHandler struct { } func (h dashboardHandler) overview(w http.ResponseWriter, req *http.Request) (interface{}, error) { - roomRef := h.netInfo.RoomID.Ref() + var ( + ctx = req.Context() + roomRef = h.netInfo.RoomID.Ref() - onlineRefs := h.roomState.List() + onlineRefs []refs.FeedRef + refsUpdateCh = make(chan []refs.FeedRef) + onlineCount = -1 + ) + // this is an attempt to sidestep the _dashboard doesn't render_ bug (issue #210) + // first we retreive the member state via a goroutine in the background + go func() { + refsUpdateCh <- h.roomState.ListAsRefs() + }() + + // if it doesn't complete in 10 seconds the slice stays empty and onlineCount remains -1 (to indicate a problem) + select { + case <-time.After(10 * time.Second): + logger := logging.FromContext(ctx) + level.Warn(logger).Log("event", "didnt retreive room state in time") + + case onlineRefs = <-refsUpdateCh: + onlineCount = len(onlineRefs) + } + + // in the timeout case, nothing will happen here since the onlineRefs slice is empty onlineMembers := make([]roomdb.Member, len(onlineRefs)) - for i := range onlineRefs { - ref, err := refs.ParseFeedRef(onlineRefs[i]) - if err != nil { - return nil, fmt.Errorf("failed to parse online ref: %w", err) - } - onlineMembers[i], err = h.dbs.Members.GetByFeed(req.Context(), *ref) + for i, ref := range onlineRefs { + var err error + onlineMembers[i], err = h.dbs.Members.GetByFeed(ctx, ref) if err != nil { // TODO: do we want to show "external users" (non-members) on the dashboard? return nil, fmt.Errorf("failed to lookup online member: %w", err) } } - onlineCount := len(onlineMembers) - - memberCount, err := h.dbs.Members.Count(req.Context()) + memberCount, err := h.dbs.Members.Count(ctx) if err != nil { return nil, fmt.Errorf("failed to count members: %w", err) } - inviteCount, err := h.dbs.Invites.Count(req.Context()) + inviteCount, err := h.dbs.Invites.Count(ctx) if err != nil { return nil, fmt.Errorf("failed to count invites: %w", err) } - deniedCount, err := h.dbs.DeniedKeys.Count(req.Context()) + deniedCount, err := h.dbs.DeniedKeys.Count(ctx) if err != nil { return nil, fmt.Errorf("failed to count denied keys: %w", err) }