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 }