1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-20 02:21:48 +08:00

namesys: select on output

License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
This commit is contained in:
Łukasz Magiera
2018-10-16 17:45:13 +02:00
parent 734615ac98
commit 7fcf56e8e5
4 changed files with 32 additions and 54 deletions

View File

@ -49,6 +49,11 @@ func resolveAsync(ctx context.Context, r resolver, name string, options opts.Res
defer close(outCh) defer close(outCh)
var subCh <-chan Result var subCh <-chan Result
var cancelSub context.CancelFunc var cancelSub context.CancelFunc
defer func() {
if cancelSub != nil {
cancelSub()
}
}()
for { for {
select { select {
@ -59,20 +64,17 @@ func resolveAsync(ctx context.Context, r resolver, name string, options opts.Res
} }
if res.err != nil { if res.err != nil {
outCh <- Result{Err: res.err} emitResult(ctx, outCh, Result{Err: res.err})
if cancelSub != nil {
cancelSub()
}
return return
} }
log.Debugf("resolved %s to %s", name, res.value.String()) log.Debugf("resolved %s to %s", name, res.value.String())
if !strings.HasPrefix(res.value.String(), ipnsPrefix) { if !strings.HasPrefix(res.value.String(), ipnsPrefix) {
outCh <- Result{Path: res.value} emitResult(ctx, outCh, Result{Path: res.value})
break break
} }
if depth == 1 { if depth == 1 {
outCh <- Result{Path: res.value, Err: ErrResolveRecursion} emitResult(ctx, outCh, Result{Path: res.value, Err: ErrResolveRecursion})
break break
} }
@ -87,6 +89,7 @@ func resolveAsync(ctx context.Context, r resolver, name string, options opts.Res
cancelSub() cancelSub()
} }
subCtx, cancelSub = context.WithCancel(ctx) subCtx, cancelSub = context.WithCancel(ctx)
_ = cancelSub
p := strings.TrimPrefix(res.value.String(), ipnsPrefix) p := strings.TrimPrefix(res.value.String(), ipnsPrefix)
subCh = resolveAsync(subCtx, r, p, subopts) subCh = resolveAsync(subCtx, r, p, subopts)
@ -96,27 +99,21 @@ func resolveAsync(ctx context.Context, r resolver, name string, options opts.Res
break break
} }
select { emitResult(ctx, outCh, res)
case outCh <- res:
case <-ctx.Done():
if cancelSub != nil {
cancelSub()
}
return
}
case <-ctx.Done(): case <-ctx.Done():
if cancelSub != nil {
cancelSub()
}
return return
} }
if resCh == nil && subCh == nil { if resCh == nil && subCh == nil {
if cancelSub != nil {
cancelSub()
}
return return
} }
} }
}() }()
return outCh return outCh
} }
func emitResult(ctx context.Context, outCh chan<- Result, r Result) {
select {
case outCh <- r:
case <-ctx.Done():
}
}

View File

@ -80,10 +80,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
} }
if subRes.error == nil { if subRes.error == nil {
p, err := appendPath(subRes.path) p, err := appendPath(subRes.path)
select { emitOnceResult(ctx, out, onceResult{value: p, err: err})
case out <- onceResult{value: p, err: err}:
case <-ctx.Done():
}
return return
} }
case rootRes, ok := <-rootChan: case rootRes, ok := <-rootChan:
@ -93,10 +90,7 @@ func (r *DNSResolver) resolveOnceAsync(ctx context.Context, name string, options
} }
if rootRes.error == nil { if rootRes.error == nil {
p, err := appendPath(rootRes.path) p, err := appendPath(rootRes.path)
select { emitOnceResult(ctx, out, onceResult{value: p, err: err})
case out <- onceResult{value: p, err: err}:
case <-ctx.Done():
}
} }
case <-ctx.Done(): case <-ctx.Done():
return return

View File

@ -141,19 +141,11 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
if len(segments) > 3 { if len(segments) > 3 {
p, err := path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3]) p, err := path.FromSegments("", strings.TrimRight(p.String(), "/"), segments[3])
if err != nil { if err != nil {
select { emitOnceResult(ctx, out, onceResult{value: p, ttl: res.ttl, err: err})
case out <- onceResult{value: p, err: err}:
case <-ctx.Done():
}
return
} }
} }
select { emitOnceResult(ctx, out, onceResult{value: p, ttl: res.ttl, err: res.err})
case out <- onceResult{value: p, ttl: res.ttl, err: res.err}:
case <-ctx.Done():
return
}
case <-ctx.Done(): case <-ctx.Done():
return return
} }
@ -163,6 +155,13 @@ func (ns *mpns) resolveOnceAsync(ctx context.Context, name string, options opts.
return out return out
} }
func emitOnceResult(ctx context.Context, outCh chan<- onceResult, r onceResult) {
select {
case outCh <- r:
case <-ctx.Done():
}
}
// Publish implements Publisher // Publish implements Publisher
func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error { func (ns *mpns) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error {
return ns.PublishWithEOL(ctx, name, value, time.Now().Add(DefaultRecordTTL)) return ns.PublishWithEOL(ctx, name, value, time.Now().Add(DefaultRecordTTL))

View File

@ -112,10 +112,7 @@ func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, option
err = proto.Unmarshal(val, entry) err = proto.Unmarshal(val, entry)
if err != nil { if err != nil {
log.Debugf("RoutingResolver: could not unmarshal value for name %s: %s", name, err) log.Debugf("RoutingResolver: could not unmarshal value for name %s: %s", name, err)
select { emitOnceResult(ctx, out, onceResult{err: err})
case out <- onceResult{err: err}:
case <-ctx.Done():
}
return return
} }
@ -129,10 +126,7 @@ func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, option
// Not a multihash, probably a new style record // Not a multihash, probably a new style record
p, err = path.ParsePath(string(entry.GetValue())) p, err = path.ParsePath(string(entry.GetValue()))
if err != nil { if err != nil {
select { emitOnceResult(ctx, out, onceResult{err: err})
case out <- onceResult{err: err}:
case <-ctx.Done():
}
return return
} }
} }
@ -154,17 +148,11 @@ func (r *IpnsResolver) resolveOnceAsync(ctx context.Context, name string, option
} }
default: default:
log.Errorf("encountered error when parsing EOL: %s", err) log.Errorf("encountered error when parsing EOL: %s", err)
select { emitOnceResult(ctx, out, onceResult{err: err})
case out <- onceResult{err: err}:
case <-ctx.Done():
}
return return
} }
select { emitOnceResult(ctx, out, onceResult{value: p, ttl: ttl})
case out <- onceResult{value: p, ttl: ttl}:
case <-ctx.Done():
}
case <-ctx.Done(): case <-ctx.Done():
return return
} }