lotus/cmd/lotus-provider/web/api/debug/debug.go

96 lines
2.3 KiB
Go
Raw Normal View History

2023-12-12 05:16:57 +00:00
// Package debug provides the API for various debug endpoints in lotus-provider.
package debug
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
logging "github.com/ipfs/go-log/v2"
"github.com/filecoin-project/lotus/build"
cliutil "github.com/filecoin-project/lotus/cli/util"
"github.com/filecoin-project/lotus/cmd/lotus-provider/deps"
)
var log = logging.Logger("lp/web/debug")
type debug struct {
*deps.Deps
}
func Routes(r *mux.Router, deps *deps.Deps) {
d := debug{deps}
r.Methods("GET").Path("chain-state-sse").HandlerFunc(d.chainStateSSE)
}
type rpcInfo struct {
Address string
CLayers []string
Reachable bool
SyncState string
Version string
}
func (d *debug) chainStateSSE(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
v1api := d.Deps.Full
ctx := r.Context()
ai := cliutil.ParseApiInfo(d.Deps.Cfg.Apis.ChainApiInfo[0])
ver, err := v1api.Version(ctx)
if err != nil {
log.Warnw("Version", "error", err)
return
}
sse:
for {
head, err := v1api.ChainHead(ctx)
if err != nil {
log.Warnw("ChainHead", "error", err)
return
}
var syncState string
switch {
case time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs*3/2): // within 1.5 epochs
syncState = "ok"
case time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelaySecs*5): // within 5 epochs
syncState = fmt.Sprintf("slow (%s behind)", time.Since(time.Unix(int64(head.MinTimestamp()), 0)).Truncate(time.Second))
default:
syncState = fmt.Sprintf("behind (%s behind)", time.Since(time.Unix(int64(head.MinTimestamp()), 0)).Truncate(time.Second))
}
select {
case <-ctx.Done():
break sse
default:
}
fmt.Fprintf(w, "data: ")
err = json.NewEncoder(w).Encode(rpcInfo{
Address: ai.Addr,
CLayers: []string{},
Reachable: true,
Version: ver.Version,
SyncState: syncState,
})
if err != nil {
log.Warnw("json encode", "error", err)
return
}
fmt.Fprintf(w, "\n\n")
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
}
}