v1.27.0-a #10
@ -164,7 +164,7 @@ func (deps *Deps) PopulateRemainingDeps(ctx context.Context, cctx *cli.Context,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
_ = j.Close()
|
_ = j.Close()
|
||||||
}()
|
}()
|
||||||
|
@ -116,10 +116,8 @@ var runCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("before populateRemainingDeps")
|
|
||||||
dependencies := &deps.Deps{}
|
dependencies := &deps.Deps{}
|
||||||
err = dependencies.PopulateRemainingDeps(ctx, cctx, true)
|
err = dependencies.PopulateRemainingDeps(ctx, cctx, true)
|
||||||
fmt.Println("after popdeps")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("err", err)
|
fmt.Println("err", err)
|
||||||
return err
|
return err
|
||||||
|
37
cmd/lotus-provider/web/hapi/routes.go
Normal file
37
cmd/lotus-provider/web/hapi/routes.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package hapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"html/template"
|
||||||
|
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/cmd/lotus-provider/deps"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed web/*
|
||||||
|
var templateFS embed.FS
|
||||||
|
|
||||||
|
func Routes(r *mux.Router, deps *deps.Deps) error {
|
||||||
|
|
||||||
|
t := new(template.Template)
|
||||||
|
t, err := t.ParseFS(templateFS, "web/*")
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("parse templates: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := &app{
|
||||||
|
db: deps.DB,
|
||||||
|
t: t,
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HandleFunc("/simpleinfo/actorsummary", a.actorSummary)
|
||||||
|
r.HandleFunc("/simpleinfo/machines", a.indexMachines)
|
||||||
|
r.HandleFunc("/simpleinfo/tasks", a.indexTasks)
|
||||||
|
r.HandleFunc("/simpleinfo/taskhistory", a.indexTasksHistory)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var log = logging.Logger("lpweb")
|
187
cmd/lotus-provider/web/hapi/simpleinfo.go
Normal file
187
cmd/lotus-provider/web/hapi/simpleinfo.go
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
package hapi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/lib/harmony/harmonydb"
|
||||||
|
)
|
||||||
|
|
||||||
|
type app struct {
|
||||||
|
db *harmonydb.DB
|
||||||
|
t *template.Template
|
||||||
|
|
||||||
|
actorInfoLk sync.Mutex
|
||||||
|
actorInfos []actorInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type actorInfo struct {
|
||||||
|
Address string
|
||||||
|
CLayers []string
|
||||||
|
|
||||||
|
QualityAdjustedPower string
|
||||||
|
RawBytePower string
|
||||||
|
|
||||||
|
Deadlines []actorDeadline
|
||||||
|
}
|
||||||
|
|
||||||
|
type actorDeadline struct {
|
||||||
|
Empty bool
|
||||||
|
Current bool
|
||||||
|
Proven bool
|
||||||
|
PartFaulty bool
|
||||||
|
Faulty bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) actorSummary(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.actorInfoLk.Lock()
|
||||||
|
defer a.actorInfoLk.Unlock()
|
||||||
|
|
||||||
|
a.executeTemplate(w, "actor_summary", a.actorInfos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) indexMachines(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s, err := a.clusterMachineSummary(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("cluster machine summary: %v", err)
|
||||||
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.executeTemplate(w, "cluster_machines", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) indexTasks(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s, err := a.clusterTaskSummary(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("cluster task summary: %v", err)
|
||||||
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.executeTemplate(w, "cluster_tasks", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) indexTasksHistory(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s, err := a.clusterTaskHistorySummary(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("cluster task history summary: %v", err)
|
||||||
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.executeTemplate(w, "cluster_task_history", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
var templateDev = os.Getenv("LOTUS_HAPI_TEMPLATE_DEV") == "1"
|
||||||
|
|
||||||
|
func (a *app) executeTemplate(w http.ResponseWriter, name string, data interface{}) {
|
||||||
|
if templateDev {
|
||||||
|
fs := os.DirFS("./cmd/lotus-provider/web/hapi/web")
|
||||||
|
a.t = template.Must(template.ParseFS(fs, "web/*"))
|
||||||
|
}
|
||||||
|
if err := a.t.ExecuteTemplate(w, name, data); err != nil {
|
||||||
|
log.Errorf("execute template %s: %v", name, err)
|
||||||
|
http.Error(w, "internal server error", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type machineSummary struct {
|
||||||
|
Address string
|
||||||
|
ID int64
|
||||||
|
SinceContact string
|
||||||
|
}
|
||||||
|
|
||||||
|
type taskSummary struct {
|
||||||
|
Name string
|
||||||
|
SincePosted string
|
||||||
|
Owner *string
|
||||||
|
ID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type taskHistorySummary struct {
|
||||||
|
Name string
|
||||||
|
TaskID int64
|
||||||
|
|
||||||
|
Posted, Start, End string
|
||||||
|
|
||||||
|
Result bool
|
||||||
|
Err string
|
||||||
|
|
||||||
|
CompletedBy string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) clusterMachineSummary(ctx context.Context) ([]machineSummary, error) {
|
||||||
|
rows, err := a.db.Query(ctx, "SELECT id, host_and_port, last_contact FROM harmony_machines")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var summaries []machineSummary
|
||||||
|
for rows.Next() {
|
||||||
|
var m machineSummary
|
||||||
|
var lastContact time.Time
|
||||||
|
|
||||||
|
if err := rows.Scan(&m.ID, &m.Address, &lastContact); err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
m.SinceContact = time.Since(lastContact).Round(time.Second).String()
|
||||||
|
|
||||||
|
summaries = append(summaries, m)
|
||||||
|
}
|
||||||
|
return summaries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) clusterTaskSummary(ctx context.Context) ([]taskSummary, error) {
|
||||||
|
rows, err := a.db.Query(ctx, "SELECT id, name, update_time, owner_id FROM harmony_task")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var summaries []taskSummary
|
||||||
|
for rows.Next() {
|
||||||
|
var t taskSummary
|
||||||
|
var posted time.Time
|
||||||
|
|
||||||
|
if err := rows.Scan(&t.ID, &t.Name, &posted, &t.Owner); err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
t.SincePosted = time.Since(posted).Round(time.Second).String()
|
||||||
|
|
||||||
|
summaries = append(summaries, t)
|
||||||
|
}
|
||||||
|
return summaries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *app) clusterTaskHistorySummary(ctx context.Context) ([]taskHistorySummary, error) {
|
||||||
|
rows, err := a.db.Query(ctx, "SELECT id, name, task_id, posted, work_start, work_end, result, err, completed_by_host_and_port FROM harmony_task_history ORDER BY work_end DESC LIMIT 15")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var summaries []taskHistorySummary
|
||||||
|
for rows.Next() {
|
||||||
|
var t taskHistorySummary
|
||||||
|
var posted, start, end time.Time
|
||||||
|
|
||||||
|
if err := rows.Scan(&t.TaskID, &t.Name, &t.TaskID, &posted, &start, &end, &t.Result, &t.Err, &t.CompletedBy); err != nil {
|
||||||
|
return nil, err // Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Posted = posted.Round(time.Second).Format("02 Jan 06 15:04")
|
||||||
|
t.Start = start.Round(time.Second).Format("02 Jan 06 15:04")
|
||||||
|
t.End = end.Round(time.Second).Format("02 Jan 06 15:04")
|
||||||
|
|
||||||
|
summaries = append(summaries, t)
|
||||||
|
}
|
||||||
|
return summaries, nil
|
||||||
|
}
|
20
cmd/lotus-provider/web/hapi/web/actor_summary.gohtml
Normal file
20
cmd/lotus-provider/web/hapi/web/actor_summary.gohtml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{{define "actor_summary"}}
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Address}}</td>
|
||||||
|
<td>
|
||||||
|
{{range .CLayers}}
|
||||||
|
<span>{{.}} </span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td>{{.QualityAdjustedPower}}</td>
|
||||||
|
<td>
|
||||||
|
<div class="deadline-box">
|
||||||
|
{{range .Deadlines}}
|
||||||
|
<div class="deadline-entry{{if .Current}} deadline-entry-cur{{end}}{{if .Proven}} deadline-proven{{end}}{{if .PartFaulty}} deadline-partially-faulty{{end}}{{if .Faulty}} deadline-faulty{{end}}"></div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
15
cmd/lotus-provider/web/hapi/web/chain_rpcs.gohtml
Normal file
15
cmd/lotus-provider/web/hapi/web/chain_rpcs.gohtml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{{define "chain_rpcs"}}
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Address}}</td>
|
||||||
|
<td>
|
||||||
|
{{range .CLayers}}
|
||||||
|
<span>{{.}} </span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td>{{if .Reachable}}<span class="success">ok</span>{{else}}<span class="error">FAIL</span>{{end}}</td>
|
||||||
|
<td>{{if eq "ok" .SyncState}}<span class="success">ok</span>{{else}}<span class="warning">{{.SyncState}}</span>{{end}}</td>
|
||||||
|
<td>{{.Version}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
10
cmd/lotus-provider/web/hapi/web/cluster_machines.gohtml
Normal file
10
cmd/lotus-provider/web/hapi/web/cluster_machines.gohtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{{define "cluster_machines"}}
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Address}}</td>
|
||||||
|
<td>{{.ID}}</td>
|
||||||
|
<td>todo</td>
|
||||||
|
<td>{{.SinceContact}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
14
cmd/lotus-provider/web/hapi/web/cluster_task_history.gohtml
Normal file
14
cmd/lotus-provider/web/hapi/web/cluster_task_history.gohtml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{{define "cluster_task_history"}}
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Name}}</td>
|
||||||
|
<td>{{.TaskID}}</td>
|
||||||
|
<td>{{.CompletedBy}}</td>
|
||||||
|
<td>{{.Posted}}</td>
|
||||||
|
<td>{{.Start}}</td>
|
||||||
|
<td>{{.End}}</td>
|
||||||
|
<td>{{if .Result}}<span class="success">success</span>{{else}}<span class="error">error</span>{{end}}</td>
|
||||||
|
<td>{{.Err}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
10
cmd/lotus-provider/web/hapi/web/cluster_tasks.gohtml
Normal file
10
cmd/lotus-provider/web/hapi/web/cluster_tasks.gohtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{{define "cluster_tasks"}}
|
||||||
|
{{range .}}
|
||||||
|
<tr>
|
||||||
|
<td>{{.Name}}</td>
|
||||||
|
<td>{{.ID}}</td>
|
||||||
|
<td>{{.SincePosted}}</td>
|
||||||
|
<td>{{.Owner}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/cmd/lotus-provider/deps"
|
"github.com/filecoin-project/lotus/cmd/lotus-provider/deps"
|
||||||
"github.com/filecoin-project/lotus/cmd/lotus-provider/web/api"
|
"github.com/filecoin-project/lotus/cmd/lotus-provider/web/api"
|
||||||
|
"github.com/filecoin-project/lotus/cmd/lotus-provider/web/hapi"
|
||||||
"github.com/filecoin-project/lotus/metrics"
|
"github.com/filecoin-project/lotus/metrics"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"go.opencensus.io/tag"
|
"go.opencensus.io/tag"
|
||||||
@ -21,6 +22,10 @@ var static embed.FS
|
|||||||
func GetSrv(ctx context.Context, deps *deps.Deps) (*http.Server, error) {
|
func GetSrv(ctx context.Context, deps *deps.Deps) (*http.Server, error) {
|
||||||
mux := mux.NewRouter()
|
mux := mux.NewRouter()
|
||||||
api.Routes(mux.PathPrefix("/api").Subrouter(), deps)
|
api.Routes(mux.PathPrefix("/api").Subrouter(), deps)
|
||||||
|
err := hapi.Routes(mux.PathPrefix("/hapi").Subrouter(), deps)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
mux.NotFoundHandler = http.FileServer(http.FS(static))
|
mux.NotFoundHandler = http.FileServer(http.FS(static))
|
||||||
|
|
||||||
return &http.Server{
|
return &http.Server{
|
||||||
|
@ -1,31 +1,45 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Lotus Provider Cluster Overview</title>
|
<title>Lotus Provider Cluster Overview</title>
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.5" integrity="sha384-xcuj3WpfgjlKF+FXhSQFQ0ZNr39ln+hwjN3npfM9VBnUskLolQAcN80McRIVOPuO" crossorigin="anonymous"></script>
|
||||||
<script type="module" src="chain-connectivity.js"></script>
|
<script type="module" src="chain-connectivity.js"></script>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html, body {
|
||||||
body {
|
|
||||||
background: #0f0f0f;
|
background: #0f0f0f;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table td, table th {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
.app-head {
|
.app-head {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.head-left {
|
.head-left {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.head-right {
|
.head-right {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td, table th {
|
||||||
|
border-left: 1px solid #f0f0f0;
|
||||||
|
padding: 1px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr td:first-child, table tr th:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
|
|
||||||
a:link {
|
a:link {
|
||||||
color: #cfc;
|
color: #cfc;
|
||||||
@ -39,6 +53,16 @@
|
|||||||
color: #af7;
|
color: #af7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.warning {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
.dash-tile {
|
.dash-tile {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -73,33 +97,29 @@
|
|||||||
.deadline-proven {
|
.deadline-proven {
|
||||||
background-color: green;
|
background-color: green;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deadline-partially-faulty {
|
.deadline-partially-faulty {
|
||||||
background-color: yellow;
|
background-color: yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deadline-faulty {
|
.deadline-faulty {
|
||||||
background-color: red;
|
background-color: red;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="app-head">
|
<div class="app-head">
|
||||||
<div class="head-left">
|
<div class="head-left">
|
||||||
<h1>Lotus Provider Cluster</h1>
|
<h1>Lotus Provider Cluster</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="head-right">
|
<div class="head-right">
|
||||||
version [todo]
|
version [todo]
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr/>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<h2>Chain Connectivity</h2>
|
<h2>Chain Connectivity</h2>
|
||||||
<chain-connectivity></chain-connectivity>
|
<chain-connectivity></chain-connectivity>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<h2>Actor Summary</h2>
|
<h2>Actor Summary</h2>
|
||||||
@ -112,70 +132,62 @@
|
|||||||
<th>Deadlines</th>
|
<th>Deadlines</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody hx-get="/hapi/simpleinfo/actorsummary" hx-trigger="load,every 5s">
|
||||||
<tr>
|
|
||||||
<td>f01234</td>
|
|
||||||
<td>mig0</td>
|
|
||||||
<td>23TiB</td>
|
|
||||||
<td>
|
|
||||||
<div class="deadline-box">
|
|
||||||
<div class="deadline-entry deadline-proven"></div>
|
|
||||||
<div class="deadline-entry deadline-partially-faulty"></div>
|
|
||||||
<div class="deadline-entry deadline-faulty"></div>
|
|
||||||
<div class="deadline-entry deadline-proven"></div>
|
|
||||||
<div class="deadline-entry deadline-proven"></div>
|
|
||||||
<div class="deadline-entry deadline-entry-cur"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
<div class="deadline-entry"></div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="info-block">
|
||||||
|
<h2>Cluster Machines</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Host</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Config Layers</th>
|
||||||
|
<th>Last Contact</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody hx-get="/hapi/simpleinfo/machines" hx-trigger="load,every 5s">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="info-block">
|
||||||
|
<h2>Recently Finished Tasks</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Executor</th>
|
||||||
|
<th>Posted</th>
|
||||||
|
<th>Start</th>
|
||||||
|
<th>End</th>
|
||||||
|
<th>Outcome</th>
|
||||||
|
<th>Message</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody hx-get="/hapi/simpleinfo/taskhistory" hx-trigger="load, every 5s">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="info-block">
|
||||||
|
<h2>Cluster Tasks</h2>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Task</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Posted</th>
|
||||||
|
<th>Owner</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody hx-get="/hapi/simpleinfo/tasks" hx-trigger="load,every 5s">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -184,6 +184,9 @@ retryRecordCompletion:
|
|||||||
return false, fmt.Errorf("could not log completion: %w", err)
|
return false, fmt.Errorf("could not log completion: %w", err)
|
||||||
}
|
}
|
||||||
result = ""
|
result = ""
|
||||||
|
if doErr != nil {
|
||||||
|
result = "non-failing error: " + doErr.Error()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if doErr != nil {
|
if doErr != nil {
|
||||||
result = "error: " + doErr.Error()
|
result = "error: " + doErr.Error()
|
||||||
|
@ -156,13 +156,18 @@ func (t *WinPostTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (don
|
|||||||
ComputeTime: details.CompTime,
|
ComputeTime: details.CompTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
persistNoWin := func() error {
|
persistNoWin := func() (bool, error) {
|
||||||
_, err := t.db.Exec(ctx, `UPDATE mining_base_block SET no_win = true WHERE task_id = $1`, taskID)
|
n, err := t.db.Exec(ctx, `UPDATE mining_base_block SET no_win = true WHERE task_id = $1`, taskID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("marking base as not-won: %w", err)
|
return false, xerrors.Errorf("marking base as not-won: %w", err)
|
||||||
|
}
|
||||||
|
log.Debugw("persisted no-win", "rows", n)
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return false, xerrors.Errorf("persist no win: no rows updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure we have a beacon entry for the epoch we're mining on
|
// ensure we have a beacon entry for the epoch we're mining on
|
||||||
@ -182,13 +187,13 @@ func (t *WinPostTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (don
|
|||||||
if mbi == nil {
|
if mbi == nil {
|
||||||
// not eligible to mine on this base, we're done here
|
// not eligible to mine on this base, we're done here
|
||||||
log.Debugw("WinPoSt not eligible to mine on this base", "tipset", types.LogCids(base.TipSet.Cids()))
|
log.Debugw("WinPoSt not eligible to mine on this base", "tipset", types.LogCids(base.TipSet.Cids()))
|
||||||
return true, persistNoWin()
|
return persistNoWin()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mbi.EligibleForMining {
|
if !mbi.EligibleForMining {
|
||||||
// slashed or just have no power yet, we're done here
|
// slashed or just have no power yet, we're done here
|
||||||
log.Debugw("WinPoSt not eligible for mining", "tipset", types.LogCids(base.TipSet.Cids()))
|
log.Debugw("WinPoSt not eligible for mining", "tipset", types.LogCids(base.TipSet.Cids()))
|
||||||
return true, persistNoWin()
|
return persistNoWin()
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(mbi.Sectors) == 0 {
|
if len(mbi.Sectors) == 0 {
|
||||||
@ -217,7 +222,7 @@ func (t *WinPostTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (don
|
|||||||
if eproof == nil {
|
if eproof == nil {
|
||||||
// not a winner, we're done here
|
// not a winner, we're done here
|
||||||
log.Debugw("WinPoSt not a winner", "tipset", types.LogCids(base.TipSet.Cids()))
|
log.Debugw("WinPoSt not a winner", "tipset", types.LogCids(base.TipSet.Cids()))
|
||||||
return true, persistNoWin()
|
return persistNoWin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user