manual.go 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. *
  3. * Copyright 2017 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package manual defines a resolver that can be used to manually send resolved
  19. // addresses to ClientConn.
  20. package manual
  21. import (
  22. "strconv"
  23. "time"
  24. "google.golang.org/grpc/resolver"
  25. )
  26. // NewBuilderWithScheme creates a new test resolver builder with the given scheme.
  27. func NewBuilderWithScheme(scheme string) *Resolver {
  28. return &Resolver{
  29. scheme: scheme,
  30. }
  31. }
  32. // Resolver is also a resolver builder.
  33. // It's build() function always returns itself.
  34. type Resolver struct {
  35. scheme string
  36. // Fields actually belong to the resolver.
  37. cc resolver.ClientConn
  38. bootstrapAddrs []resolver.Address
  39. }
  40. // InitialAddrs adds resolved addresses to the resolver so that
  41. // NewAddress doesn't need to be explicitly called after Dial.
  42. func (r *Resolver) InitialAddrs(addrs []resolver.Address) {
  43. r.bootstrapAddrs = addrs
  44. }
  45. // Build returns itself for Resolver, because it's both a builder and a resolver.
  46. func (r *Resolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
  47. r.cc = cc
  48. if r.bootstrapAddrs != nil {
  49. r.NewAddress(r.bootstrapAddrs)
  50. }
  51. return r, nil
  52. }
  53. // Scheme returns the test scheme.
  54. func (r *Resolver) Scheme() string {
  55. return r.scheme
  56. }
  57. // ResolveNow is a noop for Resolver.
  58. func (*Resolver) ResolveNow(o resolver.ResolveNowOption) {}
  59. // Close is a noop for Resolver.
  60. func (*Resolver) Close() {}
  61. // NewAddress calls cc.NewAddress.
  62. func (r *Resolver) NewAddress(addrs []resolver.Address) {
  63. r.cc.NewAddress(addrs)
  64. }
  65. // NewServiceConfig calls cc.NewServiceConfig.
  66. func (r *Resolver) NewServiceConfig(sc string) {
  67. r.cc.NewServiceConfig(sc)
  68. }
  69. // GenerateAndRegisterManualResolver generates a random scheme and a Resolver
  70. // with it. It also registers this Resolver.
  71. // It returns the Resolver and a cleanup function to unregister it.
  72. func GenerateAndRegisterManualResolver() (*Resolver, func()) {
  73. scheme := strconv.FormatInt(time.Now().UnixNano(), 36)
  74. r := NewBuilderWithScheme(scheme)
  75. resolver.Register(r)
  76. return r, func() { resolver.UnregisterForTesting(scheme) }
  77. }