github.com/searKing/golang/go@v1.2.117/net/resolver/resolve.go (about)

     1  // Copyright 2021 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package resolver
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  
    11  	sync_ "github.com/searKing/golang/go/sync"
    12  )
    13  
    14  var resolverPool = sync_.LruPool{
    15  	New: func(ctx context.Context, req any) (resp any, err error) {
    16  		target, ok := req.(string)
    17  		if !ok {
    18  			return nil, err
    19  		}
    20  		return NewResolver(ctx, target)
    21  	},
    22  	DisableKeepAlives:         false,
    23  	MaxIdleResources:          sync_.DefaultLruPool.MaxIdleResources,
    24  	MaxIdleResourcesPerBucket: 1,
    25  	MaxResourcesPerBucket:     sync_.DefaultLruPool.MaxResourcesPerBucket,
    26  	IdleResourceTimeout:       sync_.DefaultLruPool.IdleResourceTimeout,
    27  }
    28  
    29  func ResolveOneAddr(ctx context.Context, target string, opts ...ResolveOneAddrOption) (Address, error) {
    30  	_, err := GetBuilderOrDefault(target)
    31  	if err != nil {
    32  		return Address{}, err
    33  	}
    34  	resolver, put, err := resolverPool.GetOrError(ctx, target)
    35  	if err != nil {
    36  		return Address{}, err
    37  	}
    38  	defer put()
    39  	if resolver, ok := resolver.(Resolver); ok {
    40  		return resolver.ResolveOneAddr(ctx, opts...)
    41  	}
    42  	return Address{}, fmt.Errorf("could not get resolver for target: %q", target)
    43  }
    44  
    45  func ResolveAddr(ctx context.Context, target string, opts ...ResolveAddrOption) ([]Address, error) {
    46  	_, err := GetBuilderOrDefault(target)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	resolver, put, err := resolverPool.GetOrError(ctx, target)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	defer put()
    55  	if resolver, ok := resolver.(Resolver); ok {
    56  		return resolver.ResolveAddr(ctx, opts...)
    57  	}
    58  	return nil, fmt.Errorf("could not get resolver for target: %q", target)
    59  }
    60  
    61  func ResolveNow(ctx context.Context, target string, opts ...ResolveNowOption) error {
    62  	_, err := GetBuilderOrDefault(target)
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	resolver, put, err := resolverPool.GetOrError(ctx, target)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	defer put()
    72  	if resolver, ok := resolver.(Resolver); ok {
    73  		resolver.ResolveNow(ctx, opts...)
    74  		return nil
    75  	}
    76  	return fmt.Errorf("could not get resolver for target: %q", target)
    77  }
    78  
    79  func ResolveDone(ctx context.Context, target string, doneInfo DoneInfo, opts ...ResolveDoneOption) error {
    80  	_, err := GetBuilderOrDefault(target)
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	resolver, put, err := resolverPool.GetOrError(ctx, target)
    86  	if err != nil {
    87  		return err
    88  	}
    89  	defer put()
    90  	if resolver, ok := resolver.(ResolveDoneResolver); ok {
    91  		resolver.ResolveDone(ctx, doneInfo, opts...)
    92  		return nil
    93  	}
    94  	return fmt.Errorf("could not get resolver for target: %q", target)
    95  }
    96  
    97  func GetBuilderOrDefault(target string) (Builder, error) {
    98  	tgt := ParseTarget(target)
    99  	builder := Get(tgt.Scheme)
   100  	if builder == nil {
   101  		// If resolver builder is still nil, the parsed target's scheme is
   102  		// not registered. Fallback to default resolver and set Endpoint to
   103  		// the original target.
   104  		tgt.Scheme = GetDefaultScheme()
   105  		builder = Get(tgt.Scheme)
   106  		if builder == nil {
   107  			return nil, fmt.Errorf("could not get resolver for default scheme: %q (forgotten import?)", tgt.Scheme)
   108  		}
   109  	}
   110  	return builder, nil
   111  }
   112  
   113  func NewResolver(ctx context.Context, target string, opts ...BuildOption) (Resolver, error) {
   114  	tgt := ParseTarget(target)
   115  	builder := Get(tgt.Scheme)
   116  	if builder == nil {
   117  		// If resolver builder is still nil, the parsed target's scheme is
   118  		// not registered. Fallback to default resolver and set Endpoint to
   119  		// the original target.
   120  		tgt.Scheme = GetDefaultScheme()
   121  		builder = Get(tgt.Scheme)
   122  		if builder == nil {
   123  			return nil, fmt.Errorf("could not get resolver for default scheme: %q (forgotten import?)", tgt.Scheme)
   124  		}
   125  	}
   126  	return builder.Build(ctx, tgt, opts...)
   127  }