1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef GCS_CONTROL_INTERFACE_INCLUDED 24 #define GCS_CONTROL_INTERFACE_INCLUDED 25 26 #include "gcs_control_event_listener.h" 27 #include "gcs_member_identifier.h" 28 #include "gcs_view.h" 29 30 #include <vector> 31 32 /** 33 @class Gcs_control_interface 34 35 This interface represents all the control functionalities that a binding 36 implementation must provide. Like all interfaces in this API, it is 37 group-oriented, meaning that a single instance shall exist per group, 38 as it was returned by the class Gcs_interface::get_control_session. 39 40 It contains methods for: 41 - View Membership; 42 - Control Events; 43 - Generic Data Exchange. 44 45 View Membership contain operations that will conduct one to: 46 - Belong to a group: join() and leave(); 47 - Information about its status: belongs_to_group() and 48 get_current_view() that shall return the active Gcs_view. 49 50 Due to the asynchronous nature of this interface, the results of 51 join() and leave() operations, in local or remote members, shall come 52 via an event. Those events shall be delivered in form of callbacks 53 defined in Gcs_control_event_listener, that should be implemented by a 54 client of this interface interested in receiving those notifications. 55 56 Regarding Generic Data Exchange, it is a functionality that was created 57 to allow exchange of arbitrary data among members when one joins. 58 This generic data is retrieved via the callback get_exchangeable_data() each 59 time a View Change (VC) occurs. It states the data that one would like to 60 offer in exchange whenever a VC happens. 61 62 What must happen under the hood is that, when one receives a VC from 63 the underlying GCS, the binding implementation should start a round 64 of message exchange, in which members (one or all depending of the algorithm) 65 send the Exchangeable Data to the joining node. 66 67 That data is delivered when Gcs_control_event_listener::on_view_changed is 68 called, which hands-out all exchanged data in one point in time. 69 70 A typical usage for that interface would be: 71 72 @code{.cpp} 73 class my_Gcs_control_event_listener: Gcs_control_event_listener 74 { 75 void on_view_changed(const Gcs_view *new_view, 76 const Exchanged_data &exchanged_data) 77 { 78 // D something when view arrives... 79 // It will also deliver all data that nodes decided to offer at join() 80 // time 81 } 82 83 Gcs_message_data &get_exchangeable_data() 84 { 85 // Return whatever data we want to provide to a joining node 86 } 87 } 88 89 // Meanwhile in your client code... 90 Gcs_control_interface *gcs_control_interface_instance; // obtained 91 // previously 92 93 Gcs_control_event_listener *listener_instance= 94 new my_Gcs_control_event_listener(); 95 96 int ref_handler= 97 gcs_control_interface_instance->add_event_listener(listener_instance); 98 99 // Normal program flow... join(), send_message(), leave()... 100 101 gcs_control_interface_instance->join(); 102 103 gcs_control_interface_instance->leave(); 104 105 // In the end... 106 gcs_control_interface_instance->remove_event_listener(ref_handler); 107 108 @endcode 109 */ 110 class Gcs_control_interface 111 { 112 public: 113 /** 114 Method that causes one to join the group that this 115 interface pertains. 116 117 The method is non-blocking, meaning that it shall only send the 118 request to an underlying GCS. The final result shall come via a 119 View Change event delivered through Gcs_control_event_listener. 120 121 @retval GCS_OK in case of everything goes well. Any other value of 122 gcs_error in case of error. 123 */ 124 125 virtual enum_gcs_error join()= 0; 126 127 128 /** 129 Method that causes one to leave the group that this 130 interface pertains. 131 132 The method is non-blocking, meaning that it shall only send the 133 request to an underlying GCS. The final result shall come via a 134 View Change event delivered through Gcs_control_event_listener. 135 136 @retval GCS_OK in case of everything goes well. Any other value of 137 gcs_error in case of error 138 */ 139 140 virtual enum_gcs_error leave()= 0; 141 142 143 /** 144 Reports if one has joined and belongs to a group. 145 146 @retval true if belonging to a group 147 */ 148 149 virtual bool belongs_to_group()= 0; 150 151 152 /** 153 Returns the currently installed view. 154 155 @retval - a valid pointer to a Gcs_view object. 156 If one has left a group, this shall be the last 157 installed view. That view can be considered a best-effort 158 view since, in some GCSs, the one that leaves might not 159 have access to the exchanged information. 160 @retval - NULL if one never joined a group. 161 */ 162 163 virtual Gcs_view *get_current_view()= 0; 164 165 166 /** 167 Retrieves the local identifier of this member on a group. 168 169 @retval - a reference to a valid Gcs_member_identifier instance 170 @retval - NULL in case of error 171 */ 172 173 virtual const Gcs_member_identifier get_local_member_identifier() const= 0; 174 175 176 /** 177 Registers an implementation of a Gcs_control_event_listener that will 178 receive Control Events. See the class header for more details on 179 implementations and usage. 180 181 Note that a binding implementation shall not offer the possibility of 182 changing listeners while the system is up and running. In that sense, 183 listeners must be added to it only when booting up the system. 184 185 @param[in] event_listener a class that implements Gcs_control_event_listener 186 @return an handle representing the registration of this object to 187 be used in remove_event_listener 188 */ 189 190 virtual int 191 add_event_listener(const Gcs_control_event_listener &event_listener)= 0; 192 193 194 /** 195 Removes a previously registered event listener. 196 197 Note that a binding implementation shall not offer the possibility of 198 changing listeners while the system is up and running. In that sense 199 listeners must be removed from it only when shutting down the system. 200 201 @param[in] event_listener_handle the handle returned when the listener was 202 registered 203 */ 204 205 virtual void remove_event_listener(int event_listener_handle)= 0; 206 207 ~Gcs_control_interface()208 virtual ~Gcs_control_interface() {} 209 }; 210 211 #endif // GCS_CONTROL_INTERFACE_INCLUDED 212