diff --git a/core/commands/commands_test.go b/core/commands/commands_test.go index f12fbe40b..2ab3f1733 100644 --- a/core/commands/commands_test.go +++ b/core/commands/commands_test.go @@ -165,6 +165,7 @@ func TestCommands(t *testing.T) { "/ping", "/provide", "/provide/clear", + "/provide/stat", "/pubsub", "/pubsub/ls", "/pubsub/peers", diff --git a/core/commands/provide.go b/core/commands/provide.go index 97d4d8c94..ba52ca50b 100644 --- a/core/commands/provide.go +++ b/core/commands/provide.go @@ -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) +} diff --git a/core/commands/stat_provide.go b/core/commands/stat_provide.go index ef06d8e28..56a0f3dc4 100644 --- a/core/commands/stat_provide.go +++ b/core/commands/stat_provide.go @@ -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, } diff --git a/core/commands/stat_reprovide.go b/core/commands/stat_reprovide.go index 10dbc727d..0e18ceedd 100644 --- a/core/commands/stat_reprovide.go +++ b/core/commands/stat_reprovide.go @@ -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, } diff --git a/docs/changelogs/v0.37.md b/docs/changelogs/v0.37.md index 8c264275b..03d181eaa 100644 --- a/docs/changelogs/v0.37.md +++ b/docs/changelogs/v0.37.md @@ -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)