manual.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. "sync"
  23. "google.golang.org/grpc/resolver"
  24. )
  25. // NewBuilderWithScheme creates a new manual resolver builder with the given
  26. // scheme. Every instance of the manual resolver may only ever be used with a
  27. // single grpc.ClientConn. Otherwise, bad things will happen.
  28. func NewBuilderWithScheme(scheme string) *Resolver {
  29. return &Resolver{
  30. BuildCallback: func(resolver.Target, resolver.ClientConn, resolver.BuildOptions) {},
  31. UpdateStateCallback: func(error) {},
  32. ResolveNowCallback: func(resolver.ResolveNowOptions) {},
  33. CloseCallback: func() {},
  34. scheme: scheme,
  35. }
  36. }
  37. // Resolver is also a resolver builder.
  38. // It's build() function always returns itself.
  39. type Resolver struct {
  40. // BuildCallback is called when the Build method is called. Must not be
  41. // nil. Must not be changed after the resolver may be built.
  42. BuildCallback func(resolver.Target, resolver.ClientConn, resolver.BuildOptions)
  43. // UpdateStateCallback is called when the UpdateState method is called on
  44. // the resolver. The value passed as argument to this callback is the value
  45. // returned by the resolver.ClientConn. Must not be nil. Must not be
  46. // changed after the resolver may be built.
  47. UpdateStateCallback func(err error)
  48. // ResolveNowCallback is called when the ResolveNow method is called on the
  49. // resolver. Must not be nil. Must not be changed after the resolver may
  50. // be built.
  51. ResolveNowCallback func(resolver.ResolveNowOptions)
  52. // CloseCallback is called when the Close method is called. Must not be
  53. // nil. Must not be changed after the resolver may be built.
  54. CloseCallback func()
  55. scheme string
  56. // Fields actually belong to the resolver.
  57. // Guards access to below fields.
  58. mu sync.Mutex
  59. CC resolver.ClientConn
  60. // Storing the most recent state update makes this resolver resilient to
  61. // restarts, which is possible with channel idleness.
  62. lastSeenState *resolver.State
  63. }
  64. // InitialState adds initial state to the resolver so that UpdateState doesn't
  65. // need to be explicitly called after Dial.
  66. func (r *Resolver) InitialState(s resolver.State) {
  67. r.lastSeenState = &s
  68. }
  69. // Build returns itself for Resolver, because it's both a builder and a resolver.
  70. func (r *Resolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
  71. r.BuildCallback(target, cc, opts)
  72. r.mu.Lock()
  73. r.CC = cc
  74. if r.lastSeenState != nil {
  75. err := r.CC.UpdateState(*r.lastSeenState)
  76. go r.UpdateStateCallback(err)
  77. }
  78. r.mu.Unlock()
  79. return r, nil
  80. }
  81. // Scheme returns the manual resolver's scheme.
  82. func (r *Resolver) Scheme() string {
  83. return r.scheme
  84. }
  85. // ResolveNow is a noop for Resolver.
  86. func (r *Resolver) ResolveNow(o resolver.ResolveNowOptions) {
  87. r.ResolveNowCallback(o)
  88. }
  89. // Close is a noop for Resolver.
  90. func (r *Resolver) Close() {
  91. r.CloseCallback()
  92. }
  93. // UpdateState calls CC.UpdateState.
  94. func (r *Resolver) UpdateState(s resolver.State) {
  95. r.mu.Lock()
  96. err := r.CC.UpdateState(s)
  97. r.lastSeenState = &s
  98. r.mu.Unlock()
  99. r.UpdateStateCallback(err)
  100. }
  101. // ReportError calls CC.ReportError.
  102. func (r *Resolver) ReportError(err error) {
  103. r.mu.Lock()
  104. r.CC.ReportError(err)
  105. r.mu.Unlock()
  106. }