..
ipfs-cluster中add的过程
通过 ipfs-cluster-ctl 的命令行形式,看一下 Add 的流程。
1、调用 client 的 Add 方法
cerr := globalClient.Add(ctx, paths, p, out)
2、 defaultClient 中的 Add 实现
func (c *defaultClient) Add(
ctx context.Context,
paths []string,
params *api.AddParams,
out chan<- *api.AddedOutput,
) error {
ctx, span := trace.StartSpan(ctx, "client/Add")
defer span.End()
addFiles := make([]files.DirEntry, len(paths))
for i, p := range paths {
u, err := url.Parse(p)
if err != nil {
close(out)
return fmt.Errorf("error parsing path: %s", err)
}
var name string
var addFile files.Node
if strings.HasPrefix(u.Scheme, "http") {
addFile = files.NewWebFile(u)
name = path.Base(u.Path)
} else {
if params.NoCopy {
close(out)
return fmt.Errorf("nocopy option is only valid for URLs")
}
name, addFile, err = makeSerialFile(p, params)
if err != nil {
close(out)
return err
}
}
addFiles[i] = files.FileEntry(name, addFile)
}
sliceFile := files.NewSliceDirectory(addFiles)
// If `form` is set to true, the multipart data will have
// a Content-Type of 'multipart/form-data', if `form` is false,
// the Content-Type will be 'multipart/mixed'.
return c.AddMultiFile(ctx, files.NewMultiFileReader(sliceFile, true), params, out)
}
3、AddMultiFile
func (c *defaultClient) AddMultiFile(...) {
err = c.doStream(ctx,
"POST",
"/add?"+queryStr,
headers,
multiFileR,
handler,
)
}
4、doStream
func (c *defaultClient) doStream() {
resp, err := c.doRequest(ctx, method, path, headers, body)
}
5、doRequest
func (c *defaultClient) doRequest() {
return c.client.Do(r)
}
以上就是Add的一个比较粗略的过程,细节在debug时候会详解。 其中对于返回值,是通过 chan 来接收的。 看实现
1) 先创建一个带缓冲的通道 out
out := make(chan *api.AddedOutput, 1)
2) 传递该通道进入方法
cerr := globalClient.Add(ctx, paths, p, out)
3) Add 方法的形参
func (c *defaultClient) Add(
ctx context.Context,
paths []string,
params *api.AddParams,
out chan<- *api.AddedOutput,
) error
可以看到,out 通道只能进行写操作!!!
4) dec out
handler := func(dec *json.Decoder) error {
if out == nil {
return nil
}
var obj api.AddedOutput
err := dec.Decode(&obj)
if err != nil {
return err
}
out <- &obj
return nil
}
通过回调handler,解析返回结果后, 写进out通道,至此,数据返回到了上层。
Nothing