runtraversal.go 1.16 KB
Newer Older
1 2 3 4 5 6
package runtraversal

import (
	"bytes"
	"io"

7 8
	ld "gitlab.dms3.io/ld/go-ld-prime"
	"gitlab.dms3.io/ld/go-ld-prime/traversal"
Hannah Howard's avatar
Hannah Howard committed
9

10
	"gitlab.dms3.io/dms3/go-graphsync/ldutil"
11 12 13 14
)

// ResponseSender sends responses over the network
type ResponseSender func(
15
	link ld.Link,
16 17 18 19 20 21
	data []byte,
) error

// RunTraversal wraps a given loader with an interceptor that sends loaded
// blocks out to the network with the given response sender.
func RunTraversal(
22 23
	loader ld.BlockReadOpener,
	traverser ldutil.Traverser,
24 25 26 27 28 29 30
	sendResponse ResponseSender) error {
	for {
		isComplete, err := traverser.IsComplete()
		if isComplete {
			return err
		}
		lnk, lnkCtx := traverser.CurrentRequest()
Hannah Howard's avatar
Hannah Howard committed
31
		result, err := loader(lnkCtx, lnk)
32 33
		var data []byte
		if err != nil {
34
			traverser.Error(traversal.SkipMe{})
35
		} else {
36 37 38 39 40
			blockBuffer, ok := result.(*bytes.Buffer)
			if !ok {
				blockBuffer = new(bytes.Buffer)
				_, err = io.Copy(blockBuffer, result)
			}
41 42 43 44
			if err != nil {
				traverser.Error(err)
			} else {
				data = blockBuffer.Bytes()
45
				err = traverser.Advance(blockBuffer)
46 47 48 49 50 51 52 53 54 55 56
				if err != nil {
					return err
				}
			}
		}
		err = sendResponse(lnk, data)
		if err != nil {
			return err
		}
	}
}