1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-08-24 02:20:52 +08:00

refactor: move ipfs stat provide/reprovide to ipfs provide stat (#10896)

- Move `ipfs stat reprovide` to `ipfs provide stat`
- Mark `ipfs stat provide` as deprecated and replaces by `ipfs provide stat`
- Mark `ipfs stat reprovide` as deprecated and replaces by `ipfs provide stat`
- Remove redundant code from deprecated subcommands

Closes #10869
This commit is contained in:
Andrew Gillis
2025-08-07 17:17:00 -07:00
committed by GitHub
parent 58ad11b573
commit 918aa07c9e
5 changed files with 124 additions and 144 deletions

View File

@ -165,6 +165,7 @@ func TestCommands(t *testing.T) {
"/ping",
"/provide",
"/provide/clear",
"/provide/stat",
"/pubsub",
"/pubsub/ls",
"/pubsub/peers",

View File

@ -3,9 +3,15 @@ package commands
import (
"fmt"
"io"
"text/tabwriter"
"time"
humanize "github.com/dustin/go-humanize"
"github.com/ipfs/boxo/provider"
cmds "github.com/ipfs/go-ipfs-cmds"
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
"github.com/ipfs/kubo/core/commands/cmdenv"
"github.com/libp2p/go-libp2p-kad-dht/fullrt"
"golang.org/x/exp/constraints"
)
const (
@ -28,11 +34,12 @@ reprovide' provides statistics. Additionally, 'ipfs bitswap reprovide' and
},
Subcommands: map[string]*cmds.Command{
"clear": ProvideClearCmd,
"clear": provideClearCmd,
"stat": provideStatCmd,
},
}
var ProvideClearCmd = &cmds.Command{
var provideClearCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "Clear all CIDs from the provide queue.",
@ -80,3 +87,92 @@ https://github.com/ipfs/kubo/blob/master/docs/config.md#reproviderstrategy
}),
},
}
type provideStats struct {
provider.ReproviderStats
fullRT bool
}
var provideStatCmd = &cmds.Command{
Status: cmds.Experimental,
Helptext: cmds.HelpText{
Tagline: "Returns statistics about the node's provider system.",
ShortDescription: `
Returns statistics about the content the node is reproviding every
Reprovider.Interval according to Reprovider.Strategy:
https://github.com/ipfs/kubo/blob/master/docs/config.md#reprovider
This interface is not stable and may change from release to release.
`,
},
Arguments: []cmds.Argument{},
Options: []cmds.Option{},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
nd, err := cmdenv.GetNode(env)
if err != nil {
return err
}
if !nd.IsOnline {
return ErrNotOnline
}
stats, err := nd.Provider.Stat()
if err != nil {
return err
}
_, fullRT := nd.DHTClient.(*fullrt.FullRT)
if err := res.Emit(provideStats{stats, fullRT}); err != nil {
return err
}
return nil
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s provideStats) error {
wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
defer wtr.Flush()
fmt.Fprintf(wtr, "TotalReprovides:\t%s\n", humanNumber(s.TotalReprovides))
fmt.Fprintf(wtr, "AvgReprovideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration))
fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration))
if !s.LastRun.IsZero() {
fmt.Fprintf(wtr, "LastReprovide:\t%s\n", humanTime(s.LastRun))
if s.fullRT {
fmt.Fprintf(wtr, "NextReprovide:\t%s\n", humanTime(s.LastRun.Add(s.ReprovideInterval)))
}
}
return nil
}),
},
Type: provideStats{},
}
func humanDuration(val time.Duration) string {
return val.Truncate(time.Microsecond).String()
}
func humanTime(val time.Time) string {
return val.Format("2006-01-02 15:04:05")
}
func humanNumber[T constraints.Float | constraints.Integer](n T) string {
nf := float64(n)
str := humanSI(nf, 0)
fullStr := humanFull(nf, 0)
if str != fullStr {
return fmt.Sprintf("%s\t(%s)", str, fullStr)
}
return str
}
func humanSI(val float64, decimals int) string {
v, unit := humanize.ComputeSI(val)
return fmt.Sprintf("%s%s", humanFull(v, decimals), unit)
}
func humanFull(val float64, decimals int) string {
return humanize.CommafWithDigits(val, decimals)
}

View File

@ -1,65 +1,22 @@
package commands
import (
"fmt"
"io"
"text/tabwriter"
cmds "github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/kubo/core/commands/cmdenv"
"github.com/libp2p/go-libp2p-kad-dht/fullrt"
)
var statProvideCmd = &cmds.Command{
Status: cmds.Deprecated,
Helptext: cmds.HelpText{
Tagline: "Deprecated command, use 'ipfs stats reprovide' instead.",
Tagline: "Deprecated command, use 'ipfs provide stat' instead.",
ShortDescription: `
'ipfs stats provide' is deprecated because provide and reprovide operations
are now distinct. This command may be replaced by provide only stats in the
future.
`,
},
Arguments: []cmds.Argument{},
Options: []cmds.Option{},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
nd, err := cmdenv.GetNode(env)
if err != nil {
return err
}
if !nd.IsOnline {
return ErrNotOnline
}
stats, err := nd.Provider.Stat()
if err != nil {
return err
}
_, fullRT := nd.DHTClient.(*fullrt.FullRT)
if err := res.Emit(reprovideStats{stats, fullRT}); err != nil {
return err
}
return nil
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s reprovideStats) error {
wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
defer wtr.Flush()
fmt.Fprintf(wtr, "TotalProvides:\t%s\n", humanNumber(s.TotalReprovides))
fmt.Fprintf(wtr, "AvgProvideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration))
fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration))
if !s.LastRun.IsZero() {
fmt.Fprintf(wtr, "LastRun:\t%s\n", humanTime(s.LastRun))
if s.fullRT {
fmt.Fprintf(wtr, "NextRun:\t%s\n", humanTime(s.LastRun.Add(s.ReprovideInterval)))
}
}
return nil
}),
},
Type: reprovideStats{},
Arguments: provideStatCmd.Arguments,
Options: provideStatCmd.Options,
Run: provideStatCmd.Run,
Encoders: provideStatCmd.Encoders,
Type: provideStatCmd.Type,
}

View File

@ -1,104 +1,21 @@
package commands
import (
"fmt"
"io"
"text/tabwriter"
"time"
humanize "github.com/dustin/go-humanize"
"github.com/ipfs/boxo/provider"
cmds "github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/kubo/core/commands/cmdenv"
"github.com/libp2p/go-libp2p-kad-dht/fullrt"
"golang.org/x/exp/constraints"
)
type reprovideStats struct {
provider.ReproviderStats
fullRT bool
}
var statReprovideCmd = &cmds.Command{
Status: cmds.Experimental,
Status: cmds.Deprecated,
Helptext: cmds.HelpText{
Tagline: "Returns statistics about the node's reprovider system.",
Tagline: "Deprecated command, use 'ipfs provide stat' instead.",
ShortDescription: `
Returns statistics about the content the node is reproviding every
Reprovider.Interval according to Reprovider.Strategy:
https://github.com/ipfs/kubo/blob/master/docs/config.md#reprovider
This interface is not stable and may change from release to release.
'ipfs stats reprovide' is deprecated because provider stats are now
available fomr 'ipfs provide stat'.
`,
},
Arguments: []cmds.Argument{},
Options: []cmds.Option{},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
nd, err := cmdenv.GetNode(env)
if err != nil {
return err
}
if !nd.IsOnline {
return ErrNotOnline
}
stats, err := nd.Provider.Stat()
if err != nil {
return err
}
_, fullRT := nd.DHTClient.(*fullrt.FullRT)
if err := res.Emit(reprovideStats{stats, fullRT}); err != nil {
return err
}
return nil
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, s reprovideStats) error {
wtr := tabwriter.NewWriter(w, 1, 2, 1, ' ', 0)
defer wtr.Flush()
fmt.Fprintf(wtr, "TotalReprovides:\t%s\n", humanNumber(s.TotalReprovides))
fmt.Fprintf(wtr, "AvgReprovideDuration:\t%s\n", humanDuration(s.AvgReprovideDuration))
fmt.Fprintf(wtr, "LastReprovideDuration:\t%s\n", humanDuration(s.LastReprovideDuration))
if !s.LastRun.IsZero() {
fmt.Fprintf(wtr, "LastReprovide:\t%s\n", humanTime(s.LastRun))
if s.fullRT {
fmt.Fprintf(wtr, "NextReprovide:\t%s\n", humanTime(s.LastRun.Add(s.ReprovideInterval)))
}
}
return nil
}),
},
Type: reprovideStats{},
}
func humanDuration(val time.Duration) string {
return val.Truncate(time.Microsecond).String()
}
func humanTime(val time.Time) string {
return val.Format("2006-01-02 15:04:05")
}
func humanNumber[T constraints.Float | constraints.Integer](n T) string {
nf := float64(n)
str := humanSI(nf, 0)
fullStr := humanFull(nf, 0)
if str != fullStr {
return fmt.Sprintf("%s\t(%s)", str, fullStr)
}
return str
}
func humanSI(val float64, decimals int) string {
v, unit := humanize.ComputeSI(val)
return fmt.Sprintf("%s%s", humanFull(v, decimals), unit)
}
func humanFull(val float64, decimals int) string {
return humanize.CommafWithDigits(val, decimals)
Arguments: provideStatCmd.Arguments,
Options: provideStatCmd.Options,
Run: provideStatCmd.Run,
Encoders: provideStatCmd.Encoders,
Type: provideStatCmd.Type,
}

View File

@ -13,6 +13,7 @@ This release was brought to you by the [Interplanetary Shipyard](https://ipship
- [Clear provide queue when reprovide strategy changes](#clear-provide-queue-when-reprovide-strategy-changes)
- [Named pins in `ipfs add` command](#-named-pins-in-ipfs-add-command)
- [Removed unnecessary dependencies](#removed-unnecessary-dependencies)
- [Deprecated `ipfs stats reprovide`](#deprecated-ipfs-stats-reprovide)
- [📦️ Important dependency updates](#-important-dependency-updates)
- [📝 Changelog](#-changelog)
- [👨‍👩‍👧‍👦 Contributors](#-contributors)
@ -55,6 +56,14 @@ Kubo has been cleaned up by removing unnecessary dependencies and packages:
These changes reduce the dependency footprint while improving code maintainability and following Go best practices.
#### Deprecated `ipfs stats reprovide`
The `ipfs stats reprovide` command has moved to `ipfs provide stat`. This was done to organize provider commands in one location.
> [!NOTE]
> `ipfs stats reprovide` still works, but is marked as deprecated and will be removed in a future release.
#### 📦️ Important dependency updates
- update `go-libp2p` to [v0.42.1](https://github.com/libp2p/go-libp2p/releases/tag/v0.42.1)