@cryptotaxi247 / kubo / commits / a92a17452

files2.0: return errors from ufsIterator properly

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Dec 14, 2018 at 12:37 UTC a92a174526583a305f84f78b0bba0f2485ba1dfa
2 files changed +78 -4
core/coreapi/unixfile.go
+31 -4
@@ -31,7 +31,8 @@ type ufsIterator struct {
31 curName string
32 curFile files.Node
33
34 - err error
34 + err error
35 + errCh chan error
36 }
37
38 func (it *ufsIterator) Name() string {
@@ -43,11 +44,31 @@ func (it *ufsIterator) Node() files.Node {
44 }
45
46 func (it *ufsIterator) Next() bool {
46 - l, ok := <-it.files
47 - if !ok {
47 + if it.err != nil {
48 return false
49 }
50
51 + var l *ipld.Link
52 + var ok bool
53 + for !ok {
54 + if it.files == nil && it.errCh == nil {
55 + return false
56 + }
57 + select {
58 + case l, ok = <-it.files:
59 + if !ok {
60 + it.files = nil
61 + }
62 + case err := <-it.errCh:
63 + it.errCh = nil
64 + it.err = err
65 +
66 + if err != nil {
67 + return false
68 + }
69 + }
70 + }
71 +
72 it.curFile = nil
73
74 nd, err := l.GetNode(it.ctx, it.dserv)
@@ -71,8 +92,12 @@ func (d *ufsDirectory) Close() error {
92
93 func (d *ufsDirectory) Entries() files.DirIterator {
94 fileCh := make(chan *ipld.Link, prefetchFiles)
95 + errCh := make(chan error, 1)
96 go func() {
75 - d.dir.ForEachLink(d.ctx, func(link *ipld.Link) error {
97 + errCh <- d.dir.ForEachLink(d.ctx, func(link *ipld.Link) error {
98 + if d.ctx.Err() != nil {
99 + return d.ctx.Err()
100 + }
101 select {
102 case fileCh <- link:
103 case <-d.ctx.Done():
@@ -81,12 +106,14 @@ func (d *ufsDirectory) Entries() files.DirIterator {
106 return nil
107 })
108
109 + close(errCh)
110 close(fileCh)
111 }()
112
113 return &ufsIterator{
114 ctx: d.ctx,
115 files: fileCh,
116 + errCh: errCh,
117 dserv: d.dserv,
118 }
119 }
core/coreapi/unixfs_test.go
+47
@@ -776,6 +776,53 @@ func TestLs(t *testing.T) {
776 }
777 }
778
779 +func TestEntriesExpired(t *testing.T) {
780 + ctx := context.Background()
781 + node, api, err := makeAPI(ctx)
782 + if err != nil {
783 + t.Error(err)
784 + }
785 +
786 + r := strings.NewReader("content-of-file")
787 + k, _, err := coreunix.AddWrapped(node, r, "name-of-file")
788 + if err != nil {
789 + t.Error(err)
790 + }
791 + parts := strings.Split(k, "/")
792 + if len(parts) != 2 {
793 + t.Errorf("unexpected path: %s", k)
794 + }
795 + p, err := coreiface.ParsePath("/ipfs/" + parts[0])
796 + if err != nil {
797 + t.Error(err)
798 + }
799 +
800 + ctx, cancel := context.WithCancel(ctx)
801 +
802 + nd, err := api.Unixfs().Get(ctx, p)
803 + if err != nil {
804 + t.Error(err)
805 + }
806 + cancel()
807 +
808 + it := files.ToDir(nd).Entries()
809 + if it == nil {
810 + t.Fatal("it was nil")
811 + }
812 +
813 + if it.Next() {
814 + t.Fatal("Next succeeded")
815 + }
816 +
817 + if it.Err() != context.Canceled {
818 + t.Fatalf("unexpected error %s", it.Err())
819 + }
820 +
821 + if it.Next() {
822 + t.Fatal("Next succeeded")
823 + }
824 +}
825 +
826 func TestLsEmptyDir(t *testing.T) {
827 ctx := context.Background()
828 node, api, err := makeAPI(ctx)