Skip to content

Commit

Permalink
Merge pull request #742 from SiaFoundation/pj/jape
Browse files Browse the repository at this point in the history
Upgrade jape
  • Loading branch information
ChrisSchinnerl authored Nov 21, 2023
2 parents 4845a70 + 34c9332 commit ff89809
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 59 deletions.
16 changes: 9 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ jobs:
uses: golangci/golangci-lint-action@v3
with:
args: --timeout=30m
- name: Jape Analyzer
uses: SiaFoundation/action-golang-analysis@HEAD
with:
analyzers: |
go.sia.tech/jape.Analyzer@master
directories: |
autopilot
bus bus/client
worker worker/client
- name: Test
uses: n8maninger/action-golang-test@v1
with:
Expand All @@ -53,12 +62,5 @@ jobs:
with:
package: "./internal/testing/..."
args: "-race;-tags='testing';-timeout=30m"
- name: Check Endpoints
uses: SiaFoundation/action-golang-analysis@HEAD
with:
analyzers: |
go.sia.tech/jape.Analyzer
directories: |
autopilot
- name: Build
run: go build -o bin/ ./cmd/renterd
41 changes: 25 additions & 16 deletions bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -1998,10 +1998,7 @@ func (b *bus) metricsHandlerPUT(jc jape.Context) {
}

func (b *bus) metricsHandlerGET(jc jape.Context) {
key := jc.PathParam("key")

// parse mandatory query parameters
var err error
var start time.Time
var n uint64
var interval time.Duration
Expand All @@ -2014,49 +2011,61 @@ func (b *bus) metricsHandlerGET(jc jape.Context) {
}

// parse optional query parameters
switch key {
switch key := jc.PathParam("key"); key {
case api.MetricContract:
var metrics []api.ContractMetric
var opts api.ContractMetricsQueryOpts
if jc.DecodeForm("fcid", &opts.ContractID) != nil {
return
} else if jc.DecodeForm("host", &opts.HostKey) != nil {
return
} else if metrics, err = b.mtrcs.ContractMetrics(jc.Request.Context(), start, n, interval, opts); jc.Check("failed to get contract metrics", err) != nil {
} else if metrics, err := b.metrics(jc.Request.Context(), key, start, n, interval, opts); jc.Check("failed to get contract metrics", err) != nil {
return
} else {
jc.Encode(metrics)
return
}
jc.Encode(metrics)
return
case api.MetricContractSet:
var metrics []api.ContractSetMetric
var opts api.ContractSetMetricsQueryOpts
if jc.DecodeForm("name", &opts.Name) != nil {
return
} else if metrics, err = b.mtrcs.ContractSetMetrics(jc.Request.Context(), start, n, interval, opts); jc.Check("failed to get contract set metrics", err) != nil {
} else if metrics, err := b.metrics(jc.Request.Context(), key, start, n, interval, opts); jc.Check("failed to get contract set metrics", err) != nil {
return
} else {
jc.Encode(metrics)
return
}
jc.Encode(metrics)
return
case api.MetricContractSetChurn:
var metrics []api.ContractSetChurnMetric
var opts api.ContractSetChurnMetricsQueryOpts
if jc.DecodeForm("name", &opts.Name) != nil {
return
} else if jc.DecodeForm("direction", &opts.Direction) != nil {
return
} else if jc.DecodeForm("reason", &opts.Reason) != nil {
return
} else if metrics, err = b.mtrcs.ContractSetChurnMetrics(jc.Request.Context(), start, n, interval, opts); jc.Check("failed to get contract churn metrics", err) != nil {
} else if metrics, err := b.metrics(jc.Request.Context(), key, start, n, interval, opts); jc.Check("failed to get contract churn metrics", err) != nil {
return
} else {
jc.Encode(metrics)
return
}
jc.Encode(metrics)
return
default:
jc.Error(fmt.Errorf("unknown metric '%s'", key), http.StatusBadRequest)
return
}
}

func (b *bus) metrics(ctx context.Context, key string, start time.Time, n uint64, interval time.Duration, opts interface{}) (interface{}, error) {
switch key {
case api.MetricContract:
return b.mtrcs.ContractMetrics(ctx, start, n, interval, opts.(api.ContractMetricsQueryOpts))
case api.MetricContractSet:
return b.mtrcs.ContractSetMetrics(ctx, start, n, interval, opts.(api.ContractSetMetricsQueryOpts))
case api.MetricContractSetChurn:
return b.mtrcs.ContractSetChurnMetrics(ctx, start, n, interval, opts.(api.ContractSetChurnMetricsQueryOpts))
}
return nil, nil
}

func (b *bus) multipartHandlerCreatePOST(jc jape.Context) {
var req api.MultipartCreateRequest
if jc.Decode(&req) != nil {
Expand Down
73 changes: 52 additions & 21 deletions bus/client/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,32 @@ package client

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"time"

"go.sia.tech/core/types"
"go.sia.tech/renterd/api"
)

func (c *Client) ContractSetMetrics(ctx context.Context, start time.Time, n uint64, interval time.Duration, opts api.ContractSetMetricsQueryOpts) ([]api.ContractSetMetric, error) {
func (c *Client) ContractMetrics(ctx context.Context, start time.Time, n uint64, interval time.Duration, opts api.ContractMetricsQueryOpts) ([]api.ContractMetric, error) {
values := url.Values{}
values.Set("start", api.TimeRFC3339(start).String())
values.Set("n", fmt.Sprint(n))
values.Set("interval", api.DurationMS(interval).String())
if opts.Name != "" {
values.Set("name", opts.Name)
if opts.ContractID != (types.FileContractID{}) {
values.Set("fcid", opts.ContractID.String())
}
var resp []api.ContractSetMetric
err := c.c.WithContext(ctx).GET(fmt.Sprintf("/metric/%s?%s", api.MetricContractSet, values.Encode()), &resp)
if err != nil {
if opts.HostKey != (types.PublicKey{}) {
values.Set("hostKey", opts.HostKey.String())
}

var resp []api.ContractMetric
if err := c.metric(ctx, api.MetricContract, values, &resp); err != nil {
return nil, err
}
return resp, nil
Expand All @@ -40,9 +47,25 @@ func (c *Client) ContractSetChurnMetrics(ctx context.Context, start time.Time, n
if opts.Reason != "" {
values.Set("reason", string(opts.Reason))
}

var resp []api.ContractSetChurnMetric
err := c.c.WithContext(ctx).GET(fmt.Sprintf("/metric/%s?%s", api.MetricContractSetChurn, values.Encode()), &resp)
if err != nil {
if err := c.metric(ctx, api.MetricContractSetChurn, values, &resp); err != nil {
return nil, err
}
return resp, nil
}

func (c *Client) ContractSetMetrics(ctx context.Context, start time.Time, n uint64, interval time.Duration, opts api.ContractSetMetricsQueryOpts) ([]api.ContractSetMetric, error) {
values := url.Values{}
values.Set("start", api.TimeRFC3339(start).String())
values.Set("n", fmt.Sprint(n))
values.Set("interval", api.DurationMS(interval).String())
if opts.Name != "" {
values.Set("name", opts.Name)
}

var resp []api.ContractSetMetric
if err := c.metric(ctx, api.MetricContractSet, values, &resp); err != nil {
return nil, err
}
return resp, nil
Expand All @@ -54,21 +77,29 @@ func (c *Client) RecordContractSetChurnMetric(ctx context.Context, metrics ...ap
})
}

func (c *Client) ContractMetrics(ctx context.Context, start time.Time, n uint64, interval time.Duration, opts api.ContractMetricsQueryOpts) ([]api.ContractMetric, error) {
values := url.Values{}
values.Set("start", api.TimeRFC3339(start).String())
values.Set("n", fmt.Sprint(n))
values.Set("interval", api.DurationMS(interval).String())
if opts.ContractID != (types.FileContractID{}) {
values.Set("fcid", opts.ContractID.String())
func (c *Client) metric(ctx context.Context, key string, values url.Values, res interface{}) error {
c.c.Custom("GET", fmt.Sprintf("/metric/%s", key), nil, (*interface{})(nil))

u, err := url.Parse(fmt.Sprintf("%s/metric/%s", c.c.BaseURL, key))
if err != nil {
panic(err)
}
if opts.HostKey != (types.PublicKey{}) {
values.Set("hostKey", opts.HostKey.String())
u.RawQuery = values.Encode()
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
if err != nil {
panic(err)
}
var resp []api.ContractMetric
err := c.c.WithContext(ctx).GET(fmt.Sprintf("/metric/%s?%s", api.MetricContract, values.Encode()), &resp)
req.SetBasicAuth("", c.c.WithContext(ctx).Password)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
return err
}
return resp, nil
defer io.Copy(io.Discard, resp.Body)
defer resp.Body.Close()

if resp.StatusCode != 200 && resp.StatusCode != 206 {
err, _ := io.ReadAll(resp.Body)
return errors.New(string(err))
}
return json.NewDecoder(resp.Body).Decode(&res)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
go.sia.tech/core v0.1.12-0.20231011172826-6ca0ac7b3b6b
go.sia.tech/gofakes3 v0.0.0-20231109151325-e0d47c10dce2
go.sia.tech/hostd v0.2.1-0.20231013174940-920057ff41c8
go.sia.tech/jape v0.11.0
go.sia.tech/jape v0.11.1
go.sia.tech/mux v1.2.0
go.sia.tech/siad v1.5.10-0.20230228235644-3059c0b930ca
go.sia.tech/web/renterd v0.33.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ go.sia.tech/gofakes3 v0.0.0-20231109151325-e0d47c10dce2 h1:ulzfJNjxN5DjXHClkW2pT
go.sia.tech/gofakes3 v0.0.0-20231109151325-e0d47c10dce2/go.mod h1:PlsiVCn6+wssrR7bsOIlZm0DahsVrDydrlbjY4F14sg=
go.sia.tech/hostd v0.2.1-0.20231013174940-920057ff41c8 h1:0kVIAauXG2+C5EZWlnJDVtf6TrLLgB+EcObuCJyDNfY=
go.sia.tech/hostd v0.2.1-0.20231013174940-920057ff41c8/go.mod h1:B+jY+eJ2jlcowcXwYOb28N/A6/cy2dblX/WUec9pFM8=
go.sia.tech/jape v0.11.0 h1:S2JTONZ4FGl5JFmh3VFGkieuFB1wXRLImkHc859V0FY=
go.sia.tech/jape v0.11.0/go.mod h1:4QqmBB+t3W7cNplXPj++ZqpoUb2PeiS66RLpXmEGap4=
go.sia.tech/jape v0.11.1 h1:M7IP+byXL7xOqzxcHUQuXW+q3sYMkYzmMlMw+q8ZZw0=
go.sia.tech/jape v0.11.1/go.mod h1:4QqmBB+t3W7cNplXPj++ZqpoUb2PeiS66RLpXmEGap4=
go.sia.tech/mux v1.2.0 h1:ofa1Us9mdymBbGMY2XH/lSpY8itFsKIo/Aq8zwe+GHU=
go.sia.tech/mux v1.2.0/go.mod h1:Yyo6wZelOYTyvrHmJZ6aQfRoer3o4xyKQ4NmQLJrBSo=
go.sia.tech/siad v1.5.10-0.20230228235644-3059c0b930ca h1:aZMg2AKevn7jKx+wlusWQfwSM5pNU9aGtRZme29q3O4=
Expand Down
22 changes: 11 additions & 11 deletions worker/client/rhp.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ import (
)

// RHPBroadcast broadcasts the latest revision for a contract.
func (c *Client) RHPBroadcast(ctx context.Context, fcid types.FileContractID) (err error) {
err = c.c.WithContext(ctx).POST(fmt.Sprintf("/rhp/contract/%s/broadcast", fcid), nil, nil)
func (c *Client) RHPBroadcast(ctx context.Context, contractID types.FileContractID) (err error) {
err = c.c.WithContext(ctx).POST(fmt.Sprintf("/rhp/contract/%s/broadcast", contractID), nil, nil)
return
}

// RHPContractRoots fetches the roots of the contract with given id.
func (c *Client) RHPContractRoots(ctx context.Context, fcid types.FileContractID) (roots []types.Hash256, err error) {
err = c.c.WithContext(ctx).GET(fmt.Sprintf("/rhp/contract/%s/roots", fcid), &roots)
func (c *Client) RHPContractRoots(ctx context.Context, contractID types.FileContractID) (roots []types.Hash256, err error) {
err = c.c.WithContext(ctx).GET(fmt.Sprintf("/rhp/contract/%s/roots", contractID), &roots)
return
}

// RHPForm forms a contract with a host.
func (c *Client) RHPForm(ctx context.Context, endHeight uint64, hk types.PublicKey, hostIP string, renterAddress types.Address, renterFunds types.Currency, hostCollateral types.Currency) (rhpv2.ContractRevision, []types.Transaction, error) {
func (c *Client) RHPForm(ctx context.Context, endHeight uint64, hostKey types.PublicKey, hostIP string, renterAddress types.Address, renterFunds types.Currency, hostCollateral types.Currency) (rhpv2.ContractRevision, []types.Transaction, error) {
req := api.RHPFormRequest{
EndHeight: endHeight,
HostCollateral: hostCollateral,
HostKey: hk,
HostKey: hostKey,
HostIP: hostIP,
RenterFunds: renterFunds,
RenterAddress: renterAddress,
Expand Down Expand Up @@ -64,9 +64,9 @@ func (c *Client) RHPPriceTable(ctx context.Context, hostKey types.PublicKey, sia
}

// RHPPruneContract prunes deleted sectors from the contract with given id.
func (c *Client) RHPPruneContract(ctx context.Context, fcid types.FileContractID, timeout time.Duration) (pruned, remaining uint64, err error) {
func (c *Client) RHPPruneContract(ctx context.Context, contractID types.FileContractID, timeout time.Duration) (pruned, remaining uint64, err error) {
var res api.RHPPruneContractResponse
err = c.c.WithContext(ctx).POST(fmt.Sprintf("/rhp/contract/%s/prune", fcid), api.RHPPruneContractRequest{
err = c.c.WithContext(ctx).POST(fmt.Sprintf("/rhp/contract/%s/prune", contractID), api.RHPPruneContractRequest{
Timeout: api.DurationMS(timeout),
}, &res)
pruned = res.Pruned
Expand All @@ -87,12 +87,12 @@ func (c *Client) RHPReadRegistry(ctx context.Context, hostKey types.PublicKey, s
}

// RHPRenew renews an existing contract with a host.
func (c *Client) RHPRenew(ctx context.Context, fcid types.FileContractID, endHeight uint64, hk types.PublicKey, siamuxAddr string, hostAddress, renterAddress types.Address, renterFunds, newCollateral types.Currency, windowSize uint64) (rhpv2.ContractRevision, []types.Transaction, error) {
func (c *Client) RHPRenew(ctx context.Context, contractID types.FileContractID, endHeight uint64, hostKey types.PublicKey, siamuxAddr string, hostAddress, renterAddress types.Address, renterFunds, newCollateral types.Currency, windowSize uint64) (rhpv2.ContractRevision, []types.Transaction, error) {
req := api.RHPRenewRequest{
ContractID: fcid,
ContractID: contractID,
EndHeight: endHeight,
HostAddress: hostAddress,
HostKey: hk,
HostKey: hostKey,
NewCollateral: newCollateral,
RenterAddress: renterAddress,
RenterFunds: renterFunds,
Expand Down
2 changes: 1 addition & 1 deletion worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ func (w *worker) slabMigrateHandler(jc jape.Context) {

// migrate the slab
numShardsMigrated, surchargeApplied, err := migrateSlab(ctx, w.downloadManager, w.uploadManager, &slab, dlContracts, ulContracts, up.CurrentHeight, w.logger)
if jc.Check("couldn't migrate slabs", err) != nil {
if err != nil {
jc.Encode(api.MigrateSlabResponse{
NumShardsMigrated: numShardsMigrated,
SurchargeApplied: surchargeApplied,
Expand Down

0 comments on commit ff89809

Please sign in to comment.