[PALF] PALF Cluster Test Framework
This commit is contained in:
		
							
								
								
									
										197
									
								
								mittest/palf_cluster/logservice/role_coordinator_handler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								mittest/palf_cluster/logservice/role_coordinator_handler.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,197 @@ | ||||
| /** | ||||
|  * Copyright (c) 2021 OceanBase | ||||
|  * OceanBase CE is licensed under Mulan PubL v2. | ||||
|  * You can use this software according to the terms and conditions of the Mulan PubL v2. | ||||
|  * You may obtain a copy of Mulan PubL v2 at: | ||||
|  *          http://license.coscl.org.cn/MulanPubL-2.0 | ||||
|  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||||
|  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||||
|  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||||
|  * See the Mulan PubL v2 for more details. | ||||
|  */ | ||||
|  | ||||
| #include "role_coordinator_handler.h" | ||||
| #include "lib/container/ob_fixed_array.h" | ||||
| #include "lib/lock/ob_spin_lock.h" | ||||
| #include "lib/ob_define.h" | ||||
| #include "share/ob_errno.h" | ||||
| namespace oceanbase | ||||
| { | ||||
| using namespace common; | ||||
| using namespace logservice; | ||||
| namespace palfcluster | ||||
| { | ||||
|  | ||||
| ObRoleChangeHandler::ObRoleChangeHandler(): lock_(common::ObLatchIds::RCS_LOCK), | ||||
|                                             sub_role_change_handler_arr_() | ||||
| { | ||||
|   reset(); | ||||
| } | ||||
|  | ||||
| ObRoleChangeHandler::~ObRoleChangeHandler() | ||||
| { | ||||
|   reset(); | ||||
| } | ||||
|  | ||||
| void ObRoleChangeHandler::reset() | ||||
| { | ||||
|   for (int i = 0; i < ObLogBaseType::MAX_LOG_BASE_TYPE; i++) { | ||||
|     sub_role_change_handler_arr_[i] = NULL; | ||||
|   } | ||||
| } | ||||
|  | ||||
| int ObRoleChangeHandler::register_handler(const ObLogBaseType &type, | ||||
|                                           ObIRoleChangeSubHandler *role_change_handler) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObSpinLockGuard guard(lock_); | ||||
|   if (false == is_valid_log_base_type(type)) { | ||||
|     ret = OB_INVALID_ARGUMENT; | ||||
|   } else { | ||||
|     sub_role_change_handler_arr_[type] = role_change_handler; | ||||
|     CLOG_LOG(INFO, "register_handler success", K(ret), K(type), KP(role_change_handler)); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| void ObRoleChangeHandler::unregister_handler(const ObLogBaseType &type) | ||||
| { | ||||
|   ObSpinLockGuard guard(lock_); | ||||
|   if (true == is_valid_log_base_type(type)) { | ||||
|     sub_role_change_handler_arr_[type] = NULL; | ||||
|     CLOG_LOG(INFO, "unregister_handler success", K(type)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void ObRoleChangeHandler::switch_to_follower_forcedly() | ||||
| { | ||||
|   ObSpinLockGuard guard(lock_); | ||||
|   for (int i = 0; i < ObLogBaseType::MAX_LOG_BASE_TYPE; i++) { | ||||
|     ObIRoleChangeSubHandler *handler = sub_role_change_handler_arr_[i]; | ||||
|     char sub_role_change_handler_str[OB_LOG_BASE_TYPE_STR_MAX_LEN] = {'\0'}; | ||||
|     ObLogBaseType base_type = static_cast<ObLogBaseType>(i); | ||||
|     bool has_defined_to_string = false; | ||||
|     if (OB_SUCCESS == log_base_type_to_string(base_type, sub_role_change_handler_str, | ||||
|           OB_LOG_BASE_TYPE_STR_MAX_LEN)) { | ||||
|       has_defined_to_string = true; | ||||
|     } | ||||
|     if (NULL != handler) { | ||||
|       handler->switch_to_follower_forcedly(); | ||||
|       CLOG_LOG(INFO, "leader to follower forcedly, current role change handler is", | ||||
|           "cursor", i, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| int ObRoleChangeHandler::switch_to_leader() | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObSpinLockGuard guard(lock_); | ||||
|   for (int i = 0; i < ObLogBaseType::MAX_LOG_BASE_TYPE && OB_SUCC(ret); i++) { | ||||
|     ObIRoleChangeSubHandler *handler = sub_role_change_handler_arr_[i]; | ||||
|     char sub_role_change_handler_str[OB_LOG_BASE_TYPE_STR_MAX_LEN] = {'\0'}; | ||||
|     ObLogBaseType base_type = static_cast<ObLogBaseType>(i); | ||||
|     bool has_defined_to_string = false; | ||||
|     if (OB_SUCCESS == log_base_type_to_string(base_type, sub_role_change_handler_str, | ||||
|           OB_LOG_BASE_TYPE_STR_MAX_LEN)) { | ||||
|       has_defined_to_string = true; | ||||
|     } | ||||
|     if (NULL == handler) { | ||||
|     } else if (OB_FAIL(handler->switch_to_leader())) { | ||||
|       CLOG_LOG(WARN, "switch_to_leader failed", K(ret), KP(handler), K(i), | ||||
|           "cursor", i, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|     } else { | ||||
|       CLOG_LOG(INFO, "follower to leader, current role change handler is", | ||||
|           "cursor", i, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRoleChangeHandler::switch_to_follower_gracefully() | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObSpinLockGuard guard(lock_); | ||||
|   int64_t cursor = 0; | ||||
|   const int64_t count = ObLogBaseType::MAX_LOG_BASE_TYPE; | ||||
|   while (cursor < count && OB_SUCC(ret)) { | ||||
|     char sub_role_change_handler_str[OB_LOG_BASE_TYPE_STR_MAX_LEN] = {'\0'}; | ||||
|     ObLogBaseType base_type = static_cast<ObLogBaseType>(cursor); | ||||
|     bool has_defined_to_string = false; | ||||
|     if (OB_SUCCESS == log_base_type_to_string(base_type, sub_role_change_handler_str, | ||||
|           OB_LOG_BASE_TYPE_STR_MAX_LEN)) { | ||||
|       has_defined_to_string = true; | ||||
|     } | ||||
|     ObIRoleChangeSubHandler *handler = sub_role_change_handler_arr_[cursor]; | ||||
|     if (NULL == handler) { | ||||
|       cursor++; | ||||
|     } else if (OB_FAIL(handler->switch_to_follower_gracefully()) && OB_LS_NEED_REVOKE != ret) { | ||||
|       CLOG_LOG(WARN, "switch_to_follower_gracefully failed, need resume other sub modules", K(ret), | ||||
|           KP(handler), K(cursor), | ||||
|           "cursor", cursor, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|       // NB: resume_leader failed, need revoke leader. | ||||
|     } else if (OB_LS_NEED_REVOKE == ret) { | ||||
|       CLOG_LOG(WARN, "ObIRoleChangeSubHandler resume leader failed", K(ret), K(cursor)); | ||||
|     } else { | ||||
|       CLOG_LOG(INFO, "leader to follower gracefully, current role change handler is", | ||||
|           "cursor", cursor, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|       cursor++; | ||||
|     } | ||||
|   } | ||||
|   // if any sub role handler switch_to_follower_gracefully failed, and no need to revoke leader, | ||||
|   // we should resume other sub role handler, meanwhile, we should overrite 'ret' only if | ||||
|   // resume_leader_when_switch_failure_ failed. | ||||
|   if (OB_FAIL(ret) && OB_LS_NEED_REVOKE != ret) { | ||||
|     int tmp_ret = OB_SUCCESS; | ||||
|     if (OB_SUCCESS != (tmp_ret = resume_leader_when_switch_failure_(cursor))) { | ||||
|       CLOG_LOG(WARN, "resume_leader_when_switch_failure_ failed", K(tmp_ret), K(cursor)); | ||||
|       ret = tmp_ret; | ||||
|     } else { | ||||
|       CLOG_LOG(WARN, "resume_leader_when_switch_failure_ success, no need to excut follower to leader gracefully", | ||||
|           K(ret), K(tmp_ret)); | ||||
|     } | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRoleChangeHandler::resume_to_leader() | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   int cursor = ObLogBaseType::MAX_LOG_BASE_TYPE; | ||||
|   if (OB_FAIL(resume_leader_when_switch_failure_(cursor))) { | ||||
|     CLOG_LOG(WARN, "resume_leader_when_switch_failure_ failed"); | ||||
|   } else { | ||||
|     CLOG_LOG(INFO, "resume_to_leader success"); | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int ObRoleChangeHandler::resume_leader_when_switch_failure_(const int64_t cursor) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   for (int64_t i = cursor - 1; i >= 0 && OB_SUCC(ret); i--) { | ||||
|     ObIRoleChangeSubHandler *handler = sub_role_change_handler_arr_[i]; | ||||
|     ObLogBaseType base_type = static_cast<ObLogBaseType>(i); | ||||
|     char sub_role_change_handler_str[OB_LOG_BASE_TYPE_STR_MAX_LEN] = {'\0'}; | ||||
|     bool has_defined_to_string = false; | ||||
|     if (OB_SUCCESS == log_base_type_to_string(base_type, sub_role_change_handler_str, | ||||
|           OB_LOG_BASE_TYPE_STR_MAX_LEN)) { | ||||
|       has_defined_to_string = true; | ||||
|     } | ||||
|     if (NULL == handler){ | ||||
|       CLOG_LOG(INFO, "not register into role change service", K(ret), K(i)); | ||||
|     } else if (OB_FAIL(handler->resume_leader())) { | ||||
|       CLOG_LOG(WARN, "resume_leader failed", K(ret), K(i), KP(handler), | ||||
|           "cursor", i, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|     } else { | ||||
|       CLOG_LOG(INFO, "resume_leader success", K(ret), K(i), KP(handler), | ||||
|           "cursor", i, "name", has_defined_to_string ? sub_role_change_handler_str : "hasn't define to string"); | ||||
|     } | ||||
|   } | ||||
|   if (OB_FAIL(ret)) { | ||||
|     ret = OB_LS_NEED_REVOKE; | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
| } // end namespace logservice | ||||
| } // end namespace oceanbase | ||||
		Reference in New Issue
	
	Block a user
	 BinChenn
					BinChenn