96 lines
2.3 KiB
Go
96 lines
2.3 KiB
Go
|
// 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()
|
||
|
}
|
||
|
}
|
||
|
}
|