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:
@ -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():
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user