mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
fix: generate typescript types for healthcheck pkg (#8846)
This commit is contained in:
30
coderd/apidoc/docs.go
generated
30
coderd/apidoc/docs.go
generated
@ -11248,6 +11248,9 @@ const docTemplate = `{
|
||||
"$ref": "#/definitions/derp.ServerInfoMessage"
|
||||
},
|
||||
"round_trip_ping": {
|
||||
"type": "string"
|
||||
},
|
||||
"round_trip_ping_ms": {
|
||||
"type": "integer"
|
||||
},
|
||||
"stun": {
|
||||
@ -11316,7 +11319,9 @@ const docTemplate = `{
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"error": {}
|
||||
"error": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthcheck.DatabaseReport": {
|
||||
@ -11329,6 +11334,9 @@ const docTemplate = `{
|
||||
"type": "boolean"
|
||||
},
|
||||
"latency": {
|
||||
"type": "string"
|
||||
},
|
||||
"latency_ms": {
|
||||
"type": "integer"
|
||||
},
|
||||
"reachable": {
|
||||
@ -11373,20 +11381,6 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"healthcheck.WebsocketReport": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"healthy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#/definitions/healthcheck.WebsocketResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthcheck.WebsocketResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"body": {
|
||||
@ -11394,6 +11388,12 @@ const docTemplate = `{
|
||||
},
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"healthy": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
30
coderd/apidoc/swagger.json
generated
30
coderd/apidoc/swagger.json
generated
@ -10232,6 +10232,9 @@
|
||||
"$ref": "#/definitions/derp.ServerInfoMessage"
|
||||
},
|
||||
"round_trip_ping": {
|
||||
"type": "string"
|
||||
},
|
||||
"round_trip_ping_ms": {
|
||||
"type": "integer"
|
||||
},
|
||||
"stun": {
|
||||
@ -10300,7 +10303,9 @@
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"error": {}
|
||||
"error": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthcheck.DatabaseReport": {
|
||||
@ -10313,6 +10318,9 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"latency": {
|
||||
"type": "string"
|
||||
},
|
||||
"latency_ms": {
|
||||
"type": "integer"
|
||||
},
|
||||
"reachable": {
|
||||
@ -10357,20 +10365,6 @@
|
||||
}
|
||||
},
|
||||
"healthcheck.WebsocketReport": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"healthy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "#/definitions/healthcheck.WebsocketResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"healthcheck.WebsocketResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"body": {
|
||||
@ -10378,6 +10372,12 @@
|
||||
},
|
||||
"code": {
|
||||
"type": "integer"
|
||||
},
|
||||
"error": {
|
||||
"type": "string"
|
||||
},
|
||||
"healthy": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/coder/coder/coderd/util/ptr"
|
||||
)
|
||||
|
||||
// @typescript-generate AccessURLReport
|
||||
type AccessURLReport struct {
|
||||
AccessURL string `json:"access_url"`
|
||||
Healthy bool `json:"healthy"`
|
||||
|
@ -10,11 +10,13 @@ import (
|
||||
"github.com/coder/coder/coderd/database"
|
||||
)
|
||||
|
||||
// @typescript-generate DatabaseReport
|
||||
type DatabaseReport struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
Reachable bool `json:"reachable"`
|
||||
Latency time.Duration `json:"latency"`
|
||||
Error *string `json:"error"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Reachable bool `json:"reachable"`
|
||||
Latency string `json:"latency"`
|
||||
LatencyMs int `json:"latency_ms"`
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
type DatabaseReportOptions struct {
|
||||
@ -39,10 +41,12 @@ func (r *DatabaseReport) Run(ctx context.Context, opts *DatabaseReportOptions) {
|
||||
slices.Sort(pings)
|
||||
|
||||
// Take the median ping.
|
||||
r.Latency = pings[pingCount/2]
|
||||
latency := pings[pingCount/2]
|
||||
r.Latency = latency.String()
|
||||
r.LatencyMs = int(latency.Milliseconds())
|
||||
// Somewhat arbitrary, but if the latency is over 15ms, we consider it
|
||||
// unhealthy.
|
||||
if r.Latency < 15*time.Millisecond {
|
||||
if latency < 15*time.Millisecond {
|
||||
r.Healthy = true
|
||||
}
|
||||
r.Reachable = true
|
||||
|
@ -35,7 +35,8 @@ func TestDatabase(t *testing.T) {
|
||||
|
||||
assert.True(t, report.Healthy)
|
||||
assert.True(t, report.Reachable)
|
||||
assert.Equal(t, ping, report.Latency)
|
||||
assert.Equal(t, ping.String(), report.Latency)
|
||||
assert.Equal(t, int(ping.Milliseconds()), report.LatencyMs)
|
||||
assert.Nil(t, report.Error)
|
||||
})
|
||||
|
||||
@ -81,7 +82,8 @@ func TestDatabase(t *testing.T) {
|
||||
|
||||
assert.True(t, report.Healthy)
|
||||
assert.True(t, report.Reachable)
|
||||
assert.Equal(t, time.Millisecond, report.Latency)
|
||||
assert.Equal(t, time.Millisecond.String(), report.Latency)
|
||||
assert.Equal(t, 1, report.LatencyMs)
|
||||
assert.Nil(t, report.Error)
|
||||
})
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"github.com/coder/coder/coderd/util/ptr"
|
||||
)
|
||||
|
||||
// @typescript-generate DERPReport
|
||||
type DERPReport struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
|
||||
@ -36,6 +37,7 @@ type DERPReport struct {
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
// @typescript-generate DERPRegionReport
|
||||
type DERPRegionReport struct {
|
||||
mu sync.Mutex
|
||||
Healthy bool `json:"healthy"`
|
||||
@ -44,6 +46,8 @@ type DERPRegionReport struct {
|
||||
NodeReports []*DERPNodeReport `json:"node_reports"`
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
// @typescript-generate DERPNodeReport
|
||||
type DERPNodeReport struct {
|
||||
mu sync.Mutex
|
||||
clientCounter int
|
||||
@ -53,7 +57,8 @@ type DERPNodeReport struct {
|
||||
|
||||
ServerInfo derp.ServerInfoMessage `json:"node_info"`
|
||||
CanExchangeMessages bool `json:"can_exchange_messages"`
|
||||
RoundTripPing time.Duration `json:"round_trip_ping"`
|
||||
RoundTripPing string `json:"round_trip_ping"`
|
||||
RoundTripPingMs int `json:"round_trip_ping_ms"`
|
||||
UsesWebsocket bool `json:"uses_websocket"`
|
||||
ClientLogs [][]string `json:"client_logs"`
|
||||
ClientErrs [][]string `json:"client_errs"`
|
||||
@ -62,10 +67,11 @@ type DERPNodeReport struct {
|
||||
STUN DERPStunReport `json:"stun"`
|
||||
}
|
||||
|
||||
// @typescript-generate DERPStunReport
|
||||
type DERPStunReport struct {
|
||||
Enabled bool
|
||||
CanSTUN bool
|
||||
Error error
|
||||
Error *string
|
||||
}
|
||||
|
||||
type DERPReportOptions struct {
|
||||
@ -251,7 +257,9 @@ func (r *DERPNodeReport) doExchangeMessage(ctx context.Context) {
|
||||
|
||||
r.mu.Lock()
|
||||
r.CanExchangeMessages = true
|
||||
r.RoundTripPing = time.Since(*t)
|
||||
rtt := time.Since(*t)
|
||||
r.RoundTripPing = rtt.String()
|
||||
r.RoundTripPingMs = int(rtt.Milliseconds())
|
||||
r.mu.Unlock()
|
||||
|
||||
cancel()
|
||||
@ -301,20 +309,20 @@ func (r *DERPNodeReport) doSTUNTest(ctx context.Context) {
|
||||
|
||||
addr, port, err := r.stunAddr(ctx)
|
||||
if err != nil {
|
||||
r.STUN.Error = xerrors.Errorf("get stun addr: %w", err)
|
||||
r.STUN.Error = convertError(xerrors.Errorf("get stun addr: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
// We only create a prober to call ProbeUDP manually.
|
||||
p, err := prober.DERP(prober.New(), "", time.Second, time.Second, time.Second)
|
||||
if err != nil {
|
||||
r.STUN.Error = xerrors.Errorf("create prober: %w", err)
|
||||
r.STUN.Error = convertError(xerrors.Errorf("create prober: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
err = p.ProbeUDP(addr, port)(ctx)
|
||||
if err != nil {
|
||||
r.STUN.Error = xerrors.Errorf("probe stun: %w", err)
|
||||
r.STUN.Error = convertError(xerrors.Errorf("probe stun: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ func TestDERP(t *testing.T) {
|
||||
for _, node := range region.NodeReports {
|
||||
assert.True(t, node.Healthy)
|
||||
assert.True(t, node.CanExchangeMessages)
|
||||
assert.Positive(t, node.RoundTripPing)
|
||||
assert.NotEmpty(t, node.RoundTripPing)
|
||||
assert.Len(t, node.ClientLogs, 2)
|
||||
assert.Len(t, node.ClientLogs[0], 1)
|
||||
assert.Len(t, node.ClientErrs[0], 0)
|
||||
@ -76,7 +76,7 @@ func TestDERP(t *testing.T) {
|
||||
|
||||
assert.False(t, node.STUN.Enabled)
|
||||
assert.False(t, node.STUN.CanSTUN)
|
||||
assert.NoError(t, node.STUN.Error)
|
||||
assert.Nil(t, node.STUN.Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -111,7 +111,7 @@ func TestDERP(t *testing.T) {
|
||||
for _, node := range region.NodeReports {
|
||||
assert.True(t, node.Healthy)
|
||||
assert.True(t, node.CanExchangeMessages)
|
||||
assert.Positive(t, node.RoundTripPing)
|
||||
assert.NotEmpty(t, node.RoundTripPing)
|
||||
assert.Len(t, node.ClientLogs, 2)
|
||||
assert.Len(t, node.ClientLogs[0], 1)
|
||||
assert.Len(t, node.ClientErrs[0], 0)
|
||||
@ -120,7 +120,7 @@ func TestDERP(t *testing.T) {
|
||||
|
||||
assert.True(t, node.STUN.Enabled)
|
||||
assert.True(t, node.STUN.CanSTUN)
|
||||
assert.NoError(t, node.STUN.Error)
|
||||
assert.Nil(t, node.STUN.Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -174,7 +174,7 @@ func TestDERP(t *testing.T) {
|
||||
for _, node := range region.NodeReports {
|
||||
assert.False(t, node.Healthy)
|
||||
assert.True(t, node.CanExchangeMessages)
|
||||
assert.Positive(t, node.RoundTripPing)
|
||||
assert.NotEmpty(t, node.RoundTripPing)
|
||||
assert.Len(t, node.ClientLogs, 2)
|
||||
assert.Len(t, node.ClientLogs[0], 3)
|
||||
assert.Len(t, node.ClientLogs[1], 3)
|
||||
@ -185,7 +185,7 @@ func TestDERP(t *testing.T) {
|
||||
|
||||
assert.False(t, node.STUN.Enabled)
|
||||
assert.False(t, node.STUN.CanSTUN)
|
||||
assert.NoError(t, node.STUN.Error)
|
||||
assert.Nil(t, node.STUN.Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -227,7 +227,7 @@ func TestDERP(t *testing.T) {
|
||||
|
||||
assert.True(t, node.STUN.Enabled)
|
||||
assert.True(t, node.STUN.CanSTUN)
|
||||
assert.NoError(t, node.STUN.Error)
|
||||
assert.Nil(t, node.STUN.Error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -29,6 +29,7 @@ type Checker interface {
|
||||
Database(ctx context.Context, opts *DatabaseReportOptions) DatabaseReport
|
||||
}
|
||||
|
||||
// @typescript-generate Report
|
||||
type Report struct {
|
||||
// Time is the time the report was generated at.
|
||||
Time time.Time `json:"time"`
|
||||
|
@ -2,6 +2,7 @@ package healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -10,8 +11,6 @@ import (
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
"nhooyr.io/websocket"
|
||||
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
type WebsocketReportOptions struct {
|
||||
@ -20,15 +19,12 @@ type WebsocketReportOptions struct {
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// @typescript-generate WebsocketReport
|
||||
type WebsocketReport struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
Response WebsocketResponse `json:"response"`
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
type WebsocketResponse struct {
|
||||
Body string `json:"body"`
|
||||
Code int `json:"code"`
|
||||
Healthy bool `json:"healthy"`
|
||||
Body string `json:"body"`
|
||||
Code int `json:"code"`
|
||||
Error *string `json:"error"`
|
||||
}
|
||||
|
||||
func (r *WebsocketReport) Run(ctx context.Context, opts *WebsocketReportOptions) {
|
||||
@ -60,10 +56,8 @@ func (r *WebsocketReport) Run(ctx context.Context, opts *WebsocketReportOptions)
|
||||
}
|
||||
}
|
||||
|
||||
r.Response = WebsocketResponse{
|
||||
Body: body,
|
||||
Code: res.StatusCode,
|
||||
}
|
||||
r.Body = body
|
||||
r.Code = res.StatusCode
|
||||
}
|
||||
if err != nil {
|
||||
r.Error = convertError(xerrors.Errorf("websocket dial: %w", err))
|
||||
@ -115,7 +109,8 @@ func (s *WebsocketEchoServer) ServeHTTP(rw http.ResponseWriter, r *http.Request)
|
||||
ctx := r.Context()
|
||||
c, err := websocket.Accept(rw, r, &websocket.AcceptOptions{})
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, "unable to accept: "+err.Error())
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = rw.Write([]byte(fmt.Sprint("unable to accept:", err)))
|
||||
return
|
||||
}
|
||||
defer c.Close(websocket.StatusGoingAway, "goodbye")
|
||||
|
@ -63,7 +63,7 @@ func TestWebsocket(t *testing.T) {
|
||||
})
|
||||
|
||||
require.NotNil(t, wsReport.Error)
|
||||
assert.Equal(t, wsReport.Response.Body, "test error")
|
||||
assert.Equal(t, wsReport.Response.Code, http.StatusBadRequest)
|
||||
assert.Equal(t, wsReport.Body, "test error")
|
||||
assert.Equal(t, wsReport.Code, http.StatusBadRequest)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user