Пример #1
0
void KaaChannelManager::onServerFailed(ITransportConnectionInfoPtr connectionInfo) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't update server. Channel manager is down");
        return;
    }
    if (!connectionInfo) {
        KAA_LOG_WARN("Failed to process server failure: bad input data")
        throw KaaException("empty connection info pointer");
    }

    if (connectionInfo->isFailedState()) {
        KAA_LOG_DEBUG("Connection already failed. Ignoring connection failover!");
        return;
    } else {
        connectionInfo->setFailedState();
    }

    if (connectionInfo->getServerType() == ServerType::BOOTSTRAP) {
        ITransportConnectionInfoPtr nextConnectionInfo = getNextBootstrapServer(connectionInfo->getTransportId(), false);
        if (nextConnectionInfo) {
            onTransportConnectionInfoUpdated(nextConnectionInfo);
        } else {
            FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::BOOTSTRAP_SERVERS_NA);
            switch (decision.getAction()) {
                 case FailoverStrategyAction::NOOP:
                     KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
                     break;
                 case FailoverStrategyAction::RETRY:
                 {
                     std::size_t period = decision.getRetryPeriod();
                     KAA_LOG_WARN(boost::format("Attempt to reconnect to first bootstrap server will be made in %1% secs "
                             "according to failover strategy decision.") % period);
                     bsTransportId_ = connectionInfo->getTransportId();
                     retryTimer_.stop();
                     retryTimer_.start(period, [&]
                         {
                             onTransportConnectionInfoUpdated(getNextBootstrapServer(bsTransportId_, true));
                         });
                     break;
                 }
                 case FailoverStrategyAction::STOP_APP:
                     KAA_LOG_WARN("Stopping application according to failover strategy decision!");
                     exit(EXIT_FAILURE);
                     break;
                 default:
                    break;
             }
        }
    } else {
        bootstrapManager_.useNextOperationsServer(connectionInfo->getTransportId());
    }
}
Пример #2
0
void BootstrapManager::useNextOperationsServer(const TransportProtocolId& protocolId)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    auto lastServerIt = lastOperationsServers_.find(protocolId);
    auto serverIt = operationServers_.find(protocolId);

    if (lastServerIt != lastOperationsServers_.end() && serverIt != operationServers_.end()) {
        OperationsServers::iterator nextOperationIterator = (lastServerIt->second)+1;
        if (nextOperationIterator != serverIt->second.end()) {
            KAA_LOG_INFO(boost::format("New server [%1%] will be user for %2%")
                                            % (*nextOperationIterator)->getAccessPointId()
                                            % LoggingUtils::TransportProtocolIdToString(protocolId));
            lastOperationsServers_[protocolId] = nextOperationIterator;
            if (channelManager_ != nullptr) {
                channelManager_->onTransportConnectionInfoUpdated(*(nextOperationIterator));
            } else {
                KAA_LOG_ERROR("Can not process server change. Channel manager was not specified");
            }
        } else {
            KAA_LOG_WARN(boost::format("Failed to find server for channel %1%.")
                                            % LoggingUtils::TransportProtocolIdToString(protocolId));

            FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::OPERATION_SERVERS_NA);
            switch (decision.getAction()) {
                case FailoverStrategyAction::NOOP:
                    KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
                    break;
                case FailoverStrategyAction::RETRY:
                {
                    std::size_t period = decision.getRetryPeriod();
                    KAA_LOG_WARN(boost::format("Attempt to receive operations server list will be made in %1% secs "
                            "according to failover strategy decision.") % period);
                    retryTimer_.stop();
                    retryTimer_.start(period, [&] { receiveOperationsServerList(); });
                    break;
                }
                case FailoverStrategyAction::STOP_APP:
                    KAA_LOG_WARN("Stopping application according to failover strategy decision!");
                    exit(EXIT_FAILURE);
                    break;
                default:
                    break;
            }
        }
    } else {
        throw KaaException("There are no available servers at the time");
    }
}
Пример #3
0
void BootstrapManager::onServerListUpdated(const std::vector<ProtocolMetaData>& operationsServers)
{
    if (operationsServers.empty()) {
        KAA_LOG_WARN("Received empty operations server list");
        FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::NO_OPERATION_SERVERS);
        switch (decision.getAction()) {
			case FailoverStrategyAction::NOOP:
				KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
				break;
			case FailoverStrategyAction::RETRY:
			{
				std::size_t period = decision.getRetryPeriod();
				KAA_LOG_WARN(boost::format("Attempt to receive operations server list will be made in %1% secs "
						"according to failover strategy decision.") % period);
				retryTimer_.stop();
				retryTimer_.start(period, [&] { receiveOperationsServerList(); });
				break;
			}
			case FailoverStrategyAction::STOP_APP:
				KAA_LOG_WARN("Stopping application according to failover strategy decision!");
				exit(EXIT_FAILURE);
				break;
		}
        return;
    }

    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    KAA_LOG_INFO(boost::format("Received %1% new operations servers") % operationsServers.size());

    lastOperationsServers_.clear();
    operationServers_.clear();

    for (const auto& serverMetaData : operationsServers) {
        ITransportConnectionInfoPtr connectionInfo(
                new GenericTransportInfo(ServerType::OPERATIONS, serverMetaData));

        auto& servers = operationServers_[serverMetaData.protocolVersionInfo];
        servers.push_back(connectionInfo);
    }

    for (auto& transportSpecificServers : operationServers_) {
        std::shuffle (transportSpecificServers.second.begin()
                    , transportSpecificServers.second.end()
                    , std::default_random_engine(std::chrono::high_resolution_clock::now().time_since_epoch().count()));

        lastOperationsServers_[transportSpecificServers.first] =
                                    transportSpecificServers.second.begin();
    }

    if (serverToApply) {
        auto servers = getOPSByAccessPointId(*serverToApply);
        if (!servers.empty()) {
            KAA_LOG_DEBUG(boost::format("Found %1% servers by access point id %2%")
                                            % servers.size() % *serverToApply);
            serverToApply.reset();
            notifyChannelManangerAboutServer(servers);
        }
    } else {
        for (const auto& transportSpecificServers : operationServers_) {
            channelManager_->onTransportConnectionInfoUpdated(transportSpecificServers.second.front());
        }
    }
}