std::vector<std::vector<int> > mastermind_t::get_bad_groups() { try { auto cache = m_data->bad_groups.copy(); return cache.get_value(); } catch(const std::system_error &ex) { COCAINE_LOG_ERROR(m_data->m_logger, "libmastermind: get_bad_groups: \"%s\"", ex.code().message().c_str()); throw; } }
std::vector<namespace_settings_t> mastermind_t::get_namespaces_settings() { try { auto cache = m_data->namespaces_settings.copy(); return cache.get_value(); } catch(const std::system_error &ex) { COCAINE_LOG_ERROR( m_data->m_logger, "libmastermind: get_namespaces_settings; \"%s\"", ex.code().message().c_str()); throw; } }
bool mastermind_t::data::collect_elliptics_remotes() { try { auto raw_elliptics_remotes = enqueue("get_config_remotes"); auto cache = create_elliptics_remotes("", raw_elliptics_remotes); elliptics_remotes.set({std::move(cache), std::move(raw_elliptics_remotes)}); } catch (const std::exception &ex) { COCAINE_LOG_ERROR(m_logger , "libmastermind: cannot process collect_elliptics_remotes: %s" , ex.what()); } return false; }
bool mastermind_t::data::collect_cache_groups() { try { auto raw_cache_groups = enqueue("get_cached_keys"); auto cache = create_cache_groups("", raw_cache_groups); cache_groups.set({std::move(cache), std::move(raw_cache_groups)}); return true; } catch(const std::exception &ex) { COCAINE_LOG_ERROR(m_logger , "libmastermind: cannot process collect_cache_groups: %s" , ex.what()); } return false; }
std::map<int, std::vector<int>> mastermind_t::get_symmetric_groups() { try { auto cache = m_data->fake_groups_info.copy(); std::map<int, std::vector<int>> result; for (auto it = cache.get_value().begin(), end = cache.get_value().end(); it != end; ++it) { result.insert(std::make_pair(it->first, it->second.groups)); } return result; } catch(const std::system_error &ex) { COCAINE_LOG_ERROR(m_data->m_logger, "libmastermind: get_symmetric_groups: \"%s\"", ex.code().message().c_str()); throw; } }
group_info_response_t mastermind_t::get_metabalancer_group_info(int group) { try { group_info_response_t resp; { std::lock_guard<std::mutex> lock(m_data->m_mutex); (void) lock; m_data->enqueue("get_group_info", group, resp); } return resp; } catch(const std::system_error &ex) { COCAINE_LOG_ERROR( m_data->m_logger, "libmastermind: get_metabalancer_group_info: group = %d; \"%s\"", group, ex.code().message().c_str()); throw; } }
std::vector<int> mastermind_t::get_metabalancer_groups(uint64_t count, const std::string &name_space, uint64_t size) { try { auto cache = m_data->namespaces_states.copy(name_space); if (count != cache.get_value().settings.groups_count) { throw invalid_groups_count_error(); } auto couple = cache.get_value().weights.get(size); { std::ostringstream oss; oss << "libmastermind: get_metabalancer_groups: request={group-count=" << count << ", namespace=" << name_space << ", size=" << size << "}; response={" << "couple=["; { auto &&groups = couple.groups; for (auto beg = groups.begin(), it = beg, end = groups.end(); it != end; ++it) { if (beg != it) oss << ", "; oss << *it; } } oss << "], weight=" << couple.weight << ", free-space=" << couple.memory << "};"; auto msg = oss.str(); COCAINE_LOG_INFO(m_data->m_logger, "%s", msg.c_str()); } return couple.groups; } catch(const std::system_error &ex) { COCAINE_LOG_ERROR( m_data->m_logger, "libmastermind: cannot obtain couple for: count = %llu; namespace = %s; size = %llu; \"%s\"", count, name_space.c_str(), size, ex.code().message().c_str()); throw; } }
void mastermind_t::data::collect_info_loop() { std::unique_lock<std::mutex> lock(m_mutex); if (m_done) { COCAINE_LOG_INFO(m_logger, "libmastermind: have to stop immediately"); return; } try { reconnect(); } catch (const std::exception &ex) { COCAINE_LOG_ERROR(m_logger, "libmastermind: reconnect: %s", ex.what()); } #if __GNUC_MINOR__ >= 6 auto no_timeout = std::cv_status::no_timeout; auto timeout = std::cv_status::timeout; auto tm = timeout; #else bool no_timeout = true; bool timeout = false; bool tm = timeout; #endif COCAINE_LOG_INFO(m_logger, "libmastermind: collect_info_loop: update period is %d", static_cast<int>(m_group_info_update_period)); do { collect_info_loop_impl(); process_callbacks(); tm = timeout; do { tm = m_weight_cache_condition_variable.wait_for(lock, std::chrono::seconds( m_group_info_update_period)); } while(tm == no_timeout && m_done == false); } while(m_done == false); }
std::vector<int> mastermind_t::get_cache_groups(const std::string &key) { COCAINE_LOG_ERROR(m_data-> m_logger , "libmastermind: get_cache_groups: using of obsolete method"); return {}; }
void mastermind_t::data::deserialize() { std::string file; { std::ifstream input(m_cache_path.c_str()); if (input.is_open() == false) { return; } typedef std::istreambuf_iterator<char> it_t; file.assign(it_t(input), it_t()); } try { msgpack::unpacked msg; msgpack::unpack(&msg, file.data(), file.size()); msgpack::object object = msg.get(); kora::dynamic_t raw_cache; cocaine::io::type_traits<kora::dynamic_t>::unpack(object, raw_cache); auto &raw_cache_object = raw_cache.as_object(); #define TRY_UNPACK_CACHE(cache) \ do { \ try { \ cache.set(cache##_t::cache_type(raw_cache_object[#cache].as_object() \ , std::bind(&data::create_##cache, this \ , std::placeholders::_1, std::placeholders::_2) \ , #cache)); \ } catch (const std::exception &ex) { \ COCAINE_LOG_ERROR(m_logger, "libmastermind: cannot deserialize cache %s: %s" \ , #cache, ex.what()); \ } \ } while (false) #if 0 TRY_UNPACK_CACHE(cache_groups); #endif TRY_UNPACK_CACHE(elliptics_remotes); #undef TRY_UNPACK_CACHE { const auto &raw_namespaces_states = raw_cache_object["namespaces_states"]; const auto &raw_namespaces_states_object = raw_namespaces_states.as_object(); for (auto it = raw_namespaces_states_object.begin() , end = raw_namespaces_states_object.end(); it != end; ++it) { const auto &name = it->first; try { namespaces_states.set(name, namespaces_states_t::cache_type( it->second.as_object() , std::bind(&data::create_namespaces_states, this , std::placeholders::_1, std::placeholders::_2) , name)); } catch (const std::exception &ex) { COCAINE_LOG_ERROR(m_logger , "libmastermind: cannot update namespace_state for %s: %s" , name.c_str(), ex.what()); } } } cache_expire(); generate_fake_caches(); } catch (const std::exception &ex) { COCAINE_LOG_WARNING(m_logger , "libmastermind: cannot deserialize libmastermind cache: %s" , ex.what()); } catch (...) { COCAINE_LOG_WARNING(m_logger , "libmastermind: cannot deserialize libmastermind cache"); } }
void mastermind_t::data::reconnect() { std::lock_guard<std::mutex> lock(m_reconnect_mutex); (void) lock; size_t end = m_next_remote; size_t index = m_next_remote; size_t size = m_remotes.size(); do { auto &remote = m_remotes[index]; try { COCAINE_LOG_INFO(m_logger, "libmastermind: reconnect: try to connect to locator %s:%d", remote.first.c_str(), static_cast<int>(remote.second)); m_app.reset(); m_service_manager = cocaine::framework::service_manager_t::create( cocaine::framework::service_manager_t::endpoint_t(remote.first, remote.second)); COCAINE_LOG_INFO(m_logger, "libmastermind: reconnect: connected to locator, getting mastermind service"); auto g = m_service_manager->get_service_async<cocaine::framework::app_service_t>(m_worker_name); g.wait_for(reconnect_timeout); if (g.ready() == false){ COCAINE_LOG_ERROR( m_logger, "libmastermind: reconnect: cannot get mastermind-service in %d milliseconds from %s:%d", static_cast<int>(reconnect_timeout.count()), remote.first.c_str(), static_cast<int>(remote.second)); g = decltype(g)(); m_service_manager.reset(); index = (index + 1) % size; continue; } m_app = g.get(); COCAINE_LOG_INFO(m_logger, "libmastermind: reconnect: connected to mastermind via locator %s:%d" , remote.first.c_str(), static_cast<int>(remote.second)); m_current_remote = remote; m_next_remote = (index + 1) % size; return; } catch (const cocaine::framework::service_error_t &ex) { COCAINE_LOG_ERROR( m_logger, "libmastermind: reconnect: service_error: %s; host: %s:%d", ex.what(), remote.first.c_str(), static_cast<int>(remote.second)); } catch (const std::exception &ex) { COCAINE_LOG_ERROR( m_logger, "libmastermind: reconnect: %s; host: %s:%d", ex.what(), remote.first.c_str(), static_cast<int>(remote.second)); } index = (index + 1) % size; } while (index != end); m_current_remote = remote_t(); m_app.reset(); m_service_manager.reset(); COCAINE_LOG_ERROR(m_logger, "libmastermind: reconnect: cannot recconect to any host"); throw std::runtime_error("reconnect error: cannot reconnect to any host"); }