@cryptotaxi247 / kubo / commits / f338520aa

gc: add option to stream errors

License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>

Kevin Atkinson committed Mar 2, 2017 at 14:53 UTC f338520aa8dbee4c6804a63ea3f995988ac834d7
3 files changed +53 -22
core/commands/repo.go
+46 -18
@@ -40,6 +40,11 @@ var RepoCmd = &cmds.Command{
40 },
41 }
42
43 +type GcResult struct {
44 + Key *cid.Cid
45 + Error string `json:",omitempty"`
46 +}
47 +
48 var repoGcCmd = &cmds.Command{
49 Helptext: cmds.HelpText{
50 Tagline: "Perform a garbage collection sweep on the repo.",
@@ -51,6 +56,7 @@ order to reclaim hard disk space.
56 },
57 Options: []cmds.Option{
58 cmds.BoolOption("quiet", "q", "Write minimal output.").Default(false),
59 + cmds.BoolOption("stream-errors", "Stream errors.").Default(false),
60 },
61 Run: func(req cmds.Request, res cmds.Response) {
62 n, err := req.InvocContext().GetNode()
@@ -59,22 +65,41 @@ order to reclaim hard disk space.
65 return
66 }
67
68 + streamErrors, _, _ := res.Request().Option("stream-errors").Bool()
69 +
70 gcOutChan := corerepo.GarbageCollectAsync(n, req.Context())
71
64 - outChan := make(chan interface{}, len(gcOutChan))
72 + outChan := make(chan interface{}, cap(gcOutChan))
73 res.SetOutput((<-chan interface{})(outChan))
74
75 go func() {
76 defer close(outChan)
69 - err := corerepo.CollectResult(req.Context(), gcOutChan, func(k *cid.Cid) {
70 - outChan <- &corerepo.KeyRemoved{k}
71 - })
72 - if err != nil {
73 - res.SetError(err, cmds.ErrNormal)
77 + unreportedError := false
78 + var lastErr error
79 + if streamErrors {
80 + for res := range gcOutChan {
81 + if unreportedError {
82 + outChan <- &GcResult{Error: lastErr.Error()}
83 + unreportedError = false
84 + }
85 + if res.Error != nil {
86 + lastErr = res.Error
87 + unreportedError = true
88 + } else {
89 + outChan <- &GcResult{Key: res.KeyRemoved}
90 + }
91 + }
92 + } else {
93 + lastErr = corerepo.CollectResult(req.Context(), gcOutChan, func(k *cid.Cid) {
94 + outChan <- &GcResult{Key: k}
95 + })
96 + }
97 + if lastErr != nil {
98 + res.SetError(lastErr, cmds.ErrNormal)
99 }
100 }()
101 },
77 - Type: corerepo.KeyRemoved{},
102 + Type: GcResult{},
103 Marshalers: cmds.MarshalerMap{
104 cmds.Text: func(res cmds.Response) (io.Reader, error) {
105 outChan, ok := res.Output().(<-chan interface{})
@@ -87,26 +112,29 @@ order to reclaim hard disk space.
112 return nil, err
113 }
114
90 - marshal := func(v interface{}) (io.Reader, error) {
91 - obj, ok := v.(*corerepo.KeyRemoved)
115 + for v := range outChan {
116 + obj, ok := v.(*GcResult)
117 if !ok {
118 return nil, u.ErrCast()
119 }
120
96 - buf := new(bytes.Buffer)
121 + if obj.Error != "" {
122 + fmt.Fprintf(res.Stderr(), "Error: %s\n", obj.Error)
123 + continue
124 + }
125 +
126 if quiet {
98 - buf = bytes.NewBufferString(obj.Key.String() + "\n")
127 + fmt.Fprintf(res.Stdout(), "%s\n", obj.Key.String())
128 } else {
100 - buf = bytes.NewBufferString(fmt.Sprintf("removed %s\n", obj.Key))
129 + fmt.Fprintf(res.Stdout(), "removed %s\n", obj.Key.String())
130 }
102 - return buf, nil
131 }
132
105 - return &cmds.ChannelMarshaler{
106 - Channel: outChan,
107 - Marshaler: marshal,
108 - Res: res,
109 - }, nil
133 + if res.Error() != nil {
134 + return nil, res.Error()
135 + }
136 +
137 + return nil, nil
138 },
139 },
140 }
core/corerepo/gc.go
-4
@@ -20,10 +20,6 @@ var log = logging.Logger("corerepo")
20
21 var ErrMaxStorageExceeded = errors.New("Maximum storage limit exceeded. Maybe unpin some files?")
22
23 -type KeyRemoved struct {
24 - Key *cid.Cid
25 -}
26 -
23 type GC struct {
24 Node *core.IpfsNode
25 Repo repo.Repo
test/sharness/t0087-repo-robust-gc.sh
+7
@@ -134,6 +134,13 @@ test_gc_robust_part2() {
134 grep -q "aborted" repo_gc_out
135 '
136
137 + test_expect_success "'ipfs repo gc --stream-errors' should abort and report each error separately" '
138 + test_must_fail ipfs repo gc --stream-errors 2>&1 | tee repo_gc_out &&
139 + grep -q "Error: could not retrieve links for $LEAF1" repo_gc_out &&
140 + grep -q "Error: could not retrieve links for $LEAF2" repo_gc_out &&
141 + grep -q "Error: garbage collection aborted" repo_gc_out
142 + '
143 +
144 test_expect_success "unpin 1MB file" '
145 ipfs pin rm $HASH2
146 '