Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix context timout #37

Merged
merged 10 commits into from
Aug 1, 2024
8 changes: 4 additions & 4 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (d *daemon) runCheck(query url.Values) (*output, error) {
connErr := testHost.Connect(dialCtx, *ai)
dialCancel()
if connErr != nil {
out.ConnectionError = connErr.Error()
out.ConnectionError = fmt.Sprintf("error dialing to peer: %s", connErr.Error())
connectionFailed = true
}
}
Expand All @@ -175,17 +175,17 @@ func (d *daemon) runCheck(query url.Values) (*output, error) {
out.DataAvailableOverBitswap.Error = "could not connect to peer"
} else {
// If so is the data available over Bitswap?
out.DataAvailableOverBitswap = checkBitswapCID(ctx, c, ma)
out.DataAvailableOverBitswap = checkBitswapCID(ctx, testHost, c, ma)
aschmahmann marked this conversation as resolved.
Show resolved Hide resolved
}

return out, nil
}

func checkBitswapCID(ctx context.Context, c cid.Cid, ma multiaddr.Multiaddr) BitswapCheckOutput {
func checkBitswapCID(ctx context.Context, host host.Host, c cid.Cid, ma multiaddr.Multiaddr) BitswapCheckOutput {
out := BitswapCheckOutput{}
start := time.Now()

bsOut, err := vole.CheckBitswapCID(ctx, c, ma, false)
bsOut, err := vole.CheckBitswapCID(ctx, host, c, ma, false)
if err != nil {
out.Error = err.Error()
} else {
Expand Down
64 changes: 59 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"net/http"
"os"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/urfave/cli/v2"
)

Expand Down Expand Up @@ -50,17 +53,16 @@ func startServer(ctx context.Context, d *daemon, tcpListener string) error {
return err
}

log.Printf("listening on %v\n", l.Addr())
log.Printf("Libp2p host peer id %s\n", d.h.ID())
log.Printf("Libp2p host listening on %v\n", d.h.Addrs())
log.Printf("listening on %v\n", l.Addr())

d.mustStart()

log.Printf("ready to start serving")

// 1. Is the peer findable in the DHT?
// 2. Does the multiaddr work? If not, what's the error?
// 3. Is the CID in the DHT?
// 4. Does the peer respond that it has the given data over Bitswap?
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
checkHandler := func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Access-Control-Allow-Origin", "*")
data, err := d.runCheck(r.URL.Query())
if err == nil {
Expand All @@ -70,8 +72,60 @@ func startServer(ctx context.Context, d *daemon, tcpListener string) error {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
}
}

// Create a custom registry
reg := prometheus.NewRegistry()

requestsTotal := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of slow requests",
},
[]string{"code"},
)

requestDuration := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Duration of slow requests",
Buckets: prometheus.DefBuckets,
},
[]string{"code"},
)

requestsInFlight := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "slow_requests_in_flight",
Help: "Number of slow requests currently being served",
})

// Register metrics with our custom registry
reg.MustRegister(requestsTotal)
reg.MustRegister(requestDuration)
reg.MustRegister(requestsInFlight)
// Instrument the slowHandler
instrumentedHandler := promhttp.InstrumentHandlerCounter(
requestsTotal,
promhttp.InstrumentHandlerDuration(
requestDuration,
promhttp.InstrumentHandlerInFlight(
requestsInFlight,
http.HandlerFunc(checkHandler),
),
),
)

// 1. Is the peer findable in the DHT?
// 2. Does the multiaddr work? If not, what's the error?
// 3. Is the CID in the DHT?
// 4. Does the peer respond that it has the given data over Bitswap?
http.Handle("/check", instrumentedHandler)
http.Handle("/debug/libp2p", promhttp.Handler())
http.Handle("/debug/http", promhttp.HandlerFor(
aschmahmann marked this conversation as resolved.
Show resolved Hide resolved
reg,
promhttp.HandlerOpts{},
))

done := make(chan error, 1)
go func() {
defer close(done)
Expand Down
2 changes: 1 addition & 1 deletion test/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func Query(

e := httpexpect.Default(t, url)

return e.POST("/").
return e.POST("/check").
WithQuery("cid", cid).
WithQuery("multiaddr", multiaddr).
Expect().
Expand Down
40 changes: 24 additions & 16 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,22 @@ <h2 class="f4">What does it mean if I get an error?</h2>
const backendURL = getBackendUrl(formData)

showInQuery(formData) // add `cid` and `multiaddr` to local url query to make it shareable
toggleSubmitButton()
const res = await fetch(backendURL, { method: 'POST' })
toggleSubmitButton()
if (res.ok) {
const respObj = await res.json()
const output = formatOutput(formData, respObj)
showOutput(output)
} else {
const resText = await res.text()
showOutput(`⚠️ backend returned an error: ${res.status} ${resText}`)
try {
const res = await fetch(backendURL, { method: 'POST' })

if (res.ok) {
const respObj = await res.json()
const output = formatOutput(formData, respObj)
showOutput(output)
} else {
const resText = await res.text()
showOutput(`⚠️ backend returned an error: ${res.status} ${resText}`)
}
} catch (e) {
showOutput(`⚠️ backend error: ${e}`)
} finally {
toggleSubmitButton()
}
})
})
Expand Down Expand Up @@ -163,31 +169,33 @@ <h2 class="f4">What does it mean if I get an error?</h2>
function formatOutput (formData, respObj) {
const ma = formData.get('multiaddr')
const peerIDStartIndex = ma.lastIndexOf("/p2p/")
const peerID = ma.substr(peerIDStartIndex + 5, ma.length)
const addrPart = ma.substr(0, peerIDStartIndex)
const peerID = ma.slice(peerIDStartIndex + 5);
const addrPart = ma.slice(0, peerIDStartIndex);
let outText = ""

if (respObj.ConnectionError !== "") {
outText += "❌ Could not connect to multiaddr: " + respObj.ConnectionError + "\n"
} else {
outText += " Successfully connected to multiaddr\n"
outText += " Successfully connected to multiaddr\n"
}

if (ma.indexOf("/p2p/") === 0 && ma.lastIndexOf("/") === 4) {
// only peer id passed with /p2p/PeerID
if (Object.keys(respObj.PeerFoundInDHT).length === 0) {
outText += "❌ Could not find any multiaddrs in the dht\n"
} else {
outText += " Found multiaddrs advertised in the DHT:\n"
outText += " Found multiaddrs advertised in the DHT:\n"
for (const key in respObj.PeerFoundInDHT) {
outText += "\t" + key + "\n"
}
}
} else {
// a proper maddr with an IP was passed
let foundAddr = false
for (const key in respObj.PeerFoundInDHT) {
if (key === addrPart) {
foundAddr = true
outText += " Found multiaddr with " + respObj.PeerFoundInDHT[key] + " dht peers\n"
outText += " Found multiaddr with " + respObj.PeerFoundInDHT[key] + " dht peers\n"
break
}
}
Expand All @@ -200,7 +208,7 @@ <h2 class="f4">What does it mean if I get an error?</h2>
}

if (respObj.CidInDHT === true) {
outText += " Found multihash advertised in the dht\n"
outText += " Found multihash advertised in the dht\n"
} else {
outText += "❌ Could not find the multihash in the dht\n"
}
Expand All @@ -210,7 +218,7 @@ <h2 class="f4">What does it mean if I get an error?</h2>
} else if (respObj.DataAvailableOverBitswap.Responded !== true) {
outText += "❌ The peer did not quickly respond if it had the CID\n"
} else if (respObj.DataAvailableOverBitswap.Found === true) {
outText += " The peer responded that it has the CID\n"
outText += " The peer responded that it has the CID\n"
} else {
outText += "❌ The peer responded that it does not have the CID\n"
}
Expand Down
Loading