util.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2015 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package etcdserver
  15. import (
  16. "fmt"
  17. "time"
  18. "github.com/coreos/etcd/etcdserver/membership"
  19. "github.com/coreos/etcd/pkg/types"
  20. "github.com/coreos/etcd/rafthttp"
  21. )
  22. // isConnectedToQuorumSince checks whether the local member is connected to the
  23. // quorum of the cluster since the given time.
  24. func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
  25. return numConnectedSince(transport, since, self, members) >= (len(members)/2)+1
  26. }
  27. // isConnectedSince checks whether the local member is connected to the
  28. // remote member since the given time.
  29. func isConnectedSince(transport rafthttp.Transporter, since time.Time, remote types.ID) bool {
  30. t := transport.ActiveSince(remote)
  31. return !t.IsZero() && t.Before(since)
  32. }
  33. // isConnectedFullySince checks whether the local member is connected to all
  34. // members in the cluster since the given time.
  35. func isConnectedFullySince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool {
  36. return numConnectedSince(transport, since, self, members) == len(members)
  37. }
  38. // numConnectedSince counts how many members are connected to the local member
  39. // since the given time.
  40. func numConnectedSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) int {
  41. connectedNum := 0
  42. for _, m := range members {
  43. if m.ID == self || isConnectedSince(transport, since, m.ID) {
  44. connectedNum++
  45. }
  46. }
  47. return connectedNum
  48. }
  49. // longestConnected chooses the member with longest active-since-time.
  50. // It returns false, if nothing is active.
  51. func longestConnected(tp rafthttp.Transporter, membs []types.ID) (types.ID, bool) {
  52. var longest types.ID
  53. var oldest time.Time
  54. for _, id := range membs {
  55. tm := tp.ActiveSince(id)
  56. if tm.IsZero() { // inactive
  57. continue
  58. }
  59. if oldest.IsZero() { // first longest candidate
  60. oldest = tm
  61. longest = id
  62. }
  63. if tm.Before(oldest) {
  64. oldest = tm
  65. longest = id
  66. }
  67. }
  68. if uint64(longest) == 0 {
  69. return longest, false
  70. }
  71. return longest, true
  72. }
  73. type notifier struct {
  74. c chan struct{}
  75. err error
  76. }
  77. func newNotifier() *notifier {
  78. return &notifier{
  79. c: make(chan struct{}),
  80. }
  81. }
  82. func (nc *notifier) notify(err error) {
  83. nc.err = err
  84. close(nc.c)
  85. }
  86. func warnOfExpensiveRequest(now time.Time, stringer fmt.Stringer) {
  87. warnOfExpensiveGenericRequest(now, stringer, "")
  88. }
  89. func warnOfExpensiveReadOnlyRangeRequest(now time.Time, stringer fmt.Stringer) {
  90. warnOfExpensiveGenericRequest(now, stringer, "read-only range ")
  91. }
  92. func warnOfExpensiveGenericRequest(now time.Time, stringer fmt.Stringer, prefix string) {
  93. // TODO: add metrics
  94. d := time.Since(now)
  95. if d > warnApplyDuration {
  96. plog.Warningf("%srequest %q took too long (%v) to execute", prefix, stringer.String(), d)
  97. }
  98. }