mirror of
https://github.com/ipfs/kubo.git
synced 2025-07-15 07:58:15 +08:00
Report progress during 'pin add'.
License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
@ -33,6 +34,11 @@ type PinOutput struct {
|
||||
Pins []*cid.Cid
|
||||
}
|
||||
|
||||
type AddPinOutput struct {
|
||||
Pins []*cid.Cid
|
||||
Progress int `json:",omitempty"`
|
||||
}
|
||||
|
||||
var addPinCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Pin objects to local storage.",
|
||||
@ -44,8 +50,9 @@ var addPinCmd = &cmds.Command{
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.BoolOption("recursive", "r", "Recursively pin the object linked to by the specified object(s).").Default(true),
|
||||
cmds.BoolOption("progress", "Show progress"),
|
||||
},
|
||||
Type: PinOutput{},
|
||||
Type: AddPinOutput{},
|
||||
Run: func(req cmds.Request, res cmds.Response) {
|
||||
n, err := req.InvocContext().GetNode()
|
||||
if err != nil {
|
||||
@ -61,22 +68,88 @@ var addPinCmd = &cmds.Command{
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
showProgress, _, _ := req.Option("progress").Bool()
|
||||
|
||||
added, err := corerepo.Pin(n, req.Context(), req.Arguments(), recursive)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
if !showProgress {
|
||||
added, err := corerepo.Pin(n, req.Context(), req.Arguments(), recursive)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
res.SetOutput(&AddPinOutput{Pins: added})
|
||||
return
|
||||
}
|
||||
|
||||
res.SetOutput(&PinOutput{added})
|
||||
v := new(dag.ProgressTracker)
|
||||
ctx := v.DeriveContext(req.Context())
|
||||
|
||||
ch := make(chan []*cid.Cid)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
added, err := corerepo.Pin(n, ctx, req.Arguments(), recursive)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
ch <- added
|
||||
}()
|
||||
out := make(chan interface{})
|
||||
res.SetOutput((<-chan interface{})(out))
|
||||
go func() {
|
||||
ticker := time.NewTicker(500 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
defer close(out)
|
||||
for {
|
||||
select {
|
||||
case val, ok := <-ch:
|
||||
if !ok {
|
||||
// error already set just return
|
||||
return
|
||||
}
|
||||
if pv := v.Value(); pv != 0 {
|
||||
out <- &AddPinOutput{Progress: v.Value()}
|
||||
}
|
||||
out <- &AddPinOutput{Pins: val}
|
||||
return
|
||||
case <-ticker.C:
|
||||
out <- &AddPinOutput{Progress: v.Value()}
|
||||
case <-ctx.Done():
|
||||
res.SetError(ctx.Err(), cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
},
|
||||
Marshalers: cmds.MarshalerMap{
|
||||
cmds.Text: func(res cmds.Response) (io.Reader, error) {
|
||||
added, ok := res.Output().(*PinOutput)
|
||||
if !ok {
|
||||
var added []*cid.Cid
|
||||
|
||||
switch out := res.Output().(type) {
|
||||
case *AddPinOutput:
|
||||
added = out.Pins
|
||||
case <-chan interface{}:
|
||||
progressLine := false
|
||||
for r0 := range out {
|
||||
r := r0.(*AddPinOutput)
|
||||
if r.Pins != nil {
|
||||
added = r.Pins
|
||||
} else {
|
||||
if progressLine {
|
||||
fmt.Fprintf(res.Stderr(), "\r")
|
||||
}
|
||||
fmt.Fprintf(res.Stderr(), "Fetched/Processed %d nodes", r.Progress)
|
||||
progressLine = true
|
||||
}
|
||||
}
|
||||
if progressLine {
|
||||
fmt.Fprintf(res.Stderr(), "\n")
|
||||
}
|
||||
if res.Error() != nil {
|
||||
return nil, res.Error()
|
||||
}
|
||||
default:
|
||||
return nil, u.ErrCast()
|
||||
}
|
||||
|
||||
var pintype string
|
||||
rec, found, _ := res.Request().Option("recursive").Bool()
|
||||
if rec || !found {
|
||||
@ -86,7 +159,7 @@ var addPinCmd = &cmds.Command{
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
for _, k := range added.Pins {
|
||||
for _, k := range added {
|
||||
fmt.Fprintf(buf, "pinned %s %s\n", k, pintype)
|
||||
}
|
||||
return buf, nil
|
||||
|
Reference in New Issue
Block a user