Skip to content
Prev Previous commit
Next Next commit
only return recent
  • Loading branch information
f0ssel committed Sep 16, 2024
commit 7192df7daf0e8ce6d889d4ba025631d2096b0039
24 changes: 24 additions & 0 deletions coderd/database/db2sdk/db2sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,30 @@ func ProvisionerDaemon(dbDaemon database.ProvisionerDaemon) codersdk.Provisioner
return result
}

func RecentProvisionerDaemons(now time.Time, staleInterval time.Duration, daemons []database.ProvisionerDaemon) []codersdk.ProvisionerDaemon {
results := []codersdk.ProvisionerDaemon{}

// Ensure stable order for display and for tests
sort.Slice(daemons, func(i, j int) bool {
return daemons[i].Name < daemons[j].Name
})

for _, daemon := range daemons {
// Daemon never connected, skip.
if !daemon.LastSeenAt.Valid {
continue
}
// Daemon has gone away, skip.
if now.Sub(daemon.LastSeenAt.Time) > staleInterval {
continue
}

results = append(results, ProvisionerDaemon(daemon))
}

return results
}

func SlimRole(role rbac.Role) codersdk.SlimRole {
orgID := ""
if role.Identifier.OrganizationID != uuid.Nil {
Expand Down
20 changes: 3 additions & 17 deletions coderd/healthcheck/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package healthcheck

import (
"context"
"sort"
"time"

"golang.org/x/mod/semver"
Expand Down Expand Up @@ -80,23 +79,10 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
return
}

// Ensure stable order for display and for tests
sort.Slice(daemons, func(i, j int) bool {
return daemons[i].Name < daemons[j].Name
})

for _, daemon := range daemons {
// Daemon never connected, skip.
if !daemon.LastSeenAt.Valid {
continue
}
// Daemon has gone away, skip.
if now.Sub(daemon.LastSeenAt.Time) > (opts.StaleInterval) {
continue
}

recentDaemons := db2sdk.RecentProvisionerDaemons(now, opts.StaleInterval, daemons)
for _, daemon := range recentDaemons {
it := healthsdk.ProvisionerDaemonsReportItem{
ProvisionerDaemon: db2sdk.ProvisionerDaemon(daemon),
ProvisionerDaemon: daemon,
Warnings: make([]health.Message, 0),
}

Expand Down
5 changes: 4 additions & 1 deletion enterprise/coderd/provisionerdaemons.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
return
}

httpapi.Write(ctx, rw, http.StatusOK, db2sdk.List(daemons, db2sdk.ProvisionerDaemon))
// provisionerdserver.DefaultHeartbeatInterval*3 matches the healthcheck report staleInterval.
recentDaemons := db2sdk.RecentProvisionerDaemons(time.Now(), provisionerdserver.DefaultHeartbeatInterval*3, daemons)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this'll prevent the frontend from warning about non-recent provisioners. I could see this being useful as a query/filter parameter but I'm not sure it's the right default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The recency threshold here is the same as the deployment level provisioners page. If that page has non-recent warnings, I wonder if the warning threshold is lower than the "recent" threshold on the backend.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's fine to match the health page for now

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be a query param. The current stale timer is a hack imo.

In the future, we should just show the current connected provisioner daemons. They all hold open a websocket to 1 Coderd. So we could implement a method of detecting when a provisioner goes away immediately, and not wait for heartbeats.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The realtime data on connected provisioners was a reach goal for GA that we decided was not required, so I think it's totally something we can look at on a future pass.


httpapi.Write(ctx, rw, http.StatusOK, recentDaemons)
}

type provisionerDaemonAuth struct {
Expand Down