From d0512cea3d6455f4bb15837224d5d06dbab3e358 Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Tue, 14 Sep 2021 09:12:49 -0400 Subject: [PATCH 1/3] fix: give one minute timeouts to function calls instead of block retrievals to get around issues with shared IPLD ADL contexts --- resolver/resolver.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/resolver/resolver.go b/resolver/resolver.go index e42855e..06533f0 100644 --- a/resolver/resolver.go +++ b/resolver/resolver.go @@ -72,6 +72,10 @@ func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath path.Path) (cid. // create a selector to traverse and match all path segments pathSelector := pathAllSelector(p[:len(p)-1]) + // create a new cancellable session + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + // resolve node before last path segment nodes, lastCid, depth, err := r.resolveNodes(ctx, c, pathSelector) if err != nil { @@ -132,6 +136,10 @@ func (r *Resolver) ResolvePath(ctx context.Context, fpath path.Path) (ipld.Node, // create a selector to traverse all path segments but only match the last pathSelector := pathLeafSelector(p) + // create a new cancellable session + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + nodes, c, _, err := r.resolveNodes(ctx, c, pathSelector) if err != nil { return nil, nil, err @@ -172,6 +180,10 @@ func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ( // create a selector to traverse and match all path segments pathSelector := pathAllSelector(p) + // create a new cancellable session + ctx, cancel := context.WithTimeout(ctx, time.Minute) + defer cancel() + nodes, _, _, err := r.resolveNodes(ctx, c, pathSelector) if err != nil { evt.Append(logging.LoggableMap{"error": err.Error()}) @@ -218,10 +230,6 @@ func (r *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []stri // Finds nodes matching the selector starting with a cid. Returns the matched nodes, the cid of the block containing // the last node, and the depth of the last node within its block (root is depth 0). func (r *Resolver) resolveNodes(ctx context.Context, c cid.Cid, sel ipld.Node) ([]ipld.Node, cid.Cid, int, error) { - // create a new cancellable session - ctx, cancel := context.WithTimeout(ctx, time.Minute) - defer cancel() - session := r.FetcherFactory.NewSession(ctx) // traverse selector From c2dfedef9ee084ae45ff1d6269e7255a5054f89d Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 20 Sep 2021 13:04:19 -0400 Subject: [PATCH 2/3] removed timeouts for all resolver functions except for ResolveToLastNode --- resolver/resolver.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/resolver/resolver.go b/resolver/resolver.go index 06533f0..f3957c6 100644 --- a/resolver/resolver.go +++ b/resolver/resolver.go @@ -136,10 +136,6 @@ func (r *Resolver) ResolvePath(ctx context.Context, fpath path.Path) (ipld.Node, // create a selector to traverse all path segments but only match the last pathSelector := pathLeafSelector(p) - // create a new cancellable session - ctx, cancel := context.WithTimeout(ctx, time.Minute) - defer cancel() - nodes, c, _, err := r.resolveNodes(ctx, c, pathSelector) if err != nil { return nil, nil, err @@ -180,10 +176,6 @@ func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ( // create a selector to traverse and match all path segments pathSelector := pathAllSelector(p) - // create a new cancellable session - ctx, cancel := context.WithTimeout(ctx, time.Minute) - defer cancel() - nodes, _, _, err := r.resolveNodes(ctx, c, pathSelector) if err != nil { evt.Append(logging.LoggableMap{"error": err.Error()}) @@ -207,10 +199,6 @@ func (r *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []stri // create a selector to traverse and match all path segments pathSelector := pathAllSelector(names) - // create a new cancellable session - ctx, cancel := context.WithTimeout(ctx, time.Minute) - defer cancel() - session := r.FetcherFactory.NewSession(ctx) // traverse selector From 461c266805c82ecf43f70bf1fd5073743907b70f Mon Sep 17 00:00:00 2001 From: Adin Schmahmann Date: Mon, 20 Sep 2021 13:13:18 -0400 Subject: [PATCH 3/3] add warning note about context cancellation and ADLs to functions that work with fetchers and return IPLD nodes --- resolver/resolver.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resolver/resolver.go b/resolver/resolver.go index f3957c6..47dd470 100644 --- a/resolver/resolver.go +++ b/resolver/resolver.go @@ -122,6 +122,9 @@ func (r *Resolver) ResolveToLastNode(ctx context.Context, fpath path.Path) (cid. // ResolvePath fetches the node for given path. It returns the last item // returned by ResolvePathComponents and the last link traversed which can be used to recover the block. +// +// Note: if/when the context is cancelled or expires then if a multi-block ADL node is returned then it may not be +// possible to load certain values. func (r *Resolver) ResolvePath(ctx context.Context, fpath path.Path) (ipld.Node, ipld.Link, error) { // validate path if err := fpath.IsValid(); err != nil { @@ -156,6 +159,9 @@ func ResolveSingle(ctx context.Context, ds format.NodeGetter, nd format.Node, na // ResolvePathComponents fetches the nodes for each segment of the given path. // It uses the first path component as a hash (key) of the first node, then // resolves all other components walking the links via a selector traversal +// +// Note: if/when the context is cancelled or expires then if a multi-block ADL node is returned then it may not be +// possible to load certain values. func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ([]ipld.Node, error) { //lint:ignore SA1019 TODO: replace EventBegin evt := log.EventBegin(ctx, "resolvePathComponents", logging.LoggableMap{"fpath": fpath}) @@ -191,6 +197,9 @@ func (r *Resolver) ResolvePathComponents(ctx context.Context, fpath path.Path) ( // // ResolveLinks(nd, []string{"foo", "bar", "baz"}) // would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links +// +// Note: if/when the context is cancelled or expires then if a multi-block ADL node is returned then it may not be +// possible to load certain values. func (r *Resolver) ResolveLinks(ctx context.Context, ndd ipld.Node, names []string) ([]ipld.Node, error) { //lint:ignore SA1019 TODO: replace EventBegin evt := log.EventBegin(ctx, "resolveLinks", logging.LoggableMap{"names": names})