excluded_servers.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. 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,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #ifndef BRPC_EXCLUDED_SERVERS_H
  18. #define BRPC_EXCLUDED_SERVERS_H
  19. #include "butil/scoped_lock.h"
  20. #include "butil/containers/bounded_queue.h"
  21. #include "brpc/socket_id.h" // SocketId
  22. namespace brpc {
  23. // Remember servers that should be avoided in selection. These servers
  24. // are often selected in previous tries inside a RPC.
  25. class ExcludedServers {
  26. public:
  27. // Create a instance with at most `cap' servers.
  28. static ExcludedServers* Create(int cap);
  29. // Destroy the instance
  30. static void Destroy(ExcludedServers* ptr);
  31. // Add a server. If the internal queue is full, pop one from the queue first.
  32. void Add(SocketId id);
  33. // True if the server shall be excluded.
  34. bool IsExcluded(SocketId id) const;
  35. static bool IsExcluded(const ExcludedServers* s, SocketId id) {
  36. return s != NULL && s->IsExcluded(id);
  37. }
  38. // #servers inside.
  39. size_t size() const { return _l.size(); }
  40. private:
  41. ExcludedServers(int cap)
  42. : _l(_space, sizeof(SocketId)* cap, butil::NOT_OWN_STORAGE) {}
  43. ~ExcludedServers() {}
  44. // Controller::_accessed may be shared by sub channels in schan, protect
  45. // all mutable methods with this mutex. In ordinary channels, this mutex
  46. // is never contended.
  47. mutable butil::Mutex _mutex;
  48. butil::BoundedQueue<SocketId> _l;
  49. SocketId _space[0];
  50. };
  51. // ===================================================
  52. inline ExcludedServers* ExcludedServers::Create(int cap) {
  53. void *space = malloc(
  54. offsetof(ExcludedServers, _space) + sizeof(SocketId) * cap);
  55. if (NULL == space) {
  56. return NULL;
  57. }
  58. return new (space) ExcludedServers(cap);
  59. }
  60. inline void ExcludedServers::Destroy(ExcludedServers* ptr) {
  61. if (ptr) {
  62. ptr->~ExcludedServers();
  63. free(ptr);
  64. }
  65. }
  66. inline void ExcludedServers::Add(SocketId id) {
  67. BAIDU_SCOPED_LOCK(_mutex);
  68. const SocketId* last_id = _l.bottom();
  69. if (last_id == NULL || *last_id != id) {
  70. _l.elim_push(id);
  71. }
  72. }
  73. inline bool ExcludedServers::IsExcluded(SocketId id) const {
  74. BAIDU_SCOPED_LOCK(_mutex);
  75. for (size_t i = 0; i < _l.size(); ++i) {
  76. if (*_l.bottom(i) == id) {
  77. return true;
  78. }
  79. }
  80. return false;
  81. }
  82. } // namespace brpc
  83. #endif // BRPC_EXCLUDED_SERVERS_H