コード例 #1
0
ファイル: interpolator.cpp プロジェクト: jyzhang-bjtu/hpx
    hpx::naming::id_type const&
    interpolator::get_id(double ye, double temp, double rho)  const
    {
        std::size_t x = get_partition_index(dimension::ye, ye);
        std::size_t y = get_partition_index(dimension::temp, std::log10(temp));
        std::size_t z = get_partition_index(dimension::rho, std::log10(rho));

        std::size_t index =
            x + (y + z * num_partitions_per_dim_) * num_partitions_per_dim_;
        HPX_ASSERT(index < partitions_.size());

        return partitions_[index];
    }
コード例 #2
0
        void partition_resolver_simple::query_config_reply(error_code err, dsn_message_t request, dsn_message_t response, int partition_index)
        {
            auto client_err = ERR_OK;

            if (err == ERR_OK)
            {
                configuration_query_by_index_response resp;
                unmarshall(response, resp);
                if (resp.err == ERR_OK)
                {
                    zauto_write_lock l(_config_lock);

                    if (_app_id != -1 && _app_id != resp.app_id)
                    {
                        dassert(false, "app id is changed (mostly the app was removed and created with the same name), local Vs remote: %u vs %u ",
                            _app_id, resp.app_id);
                    }
                    if (_app_partition_count != -1 && _app_partition_count != resp.partition_count)
                    {
                        dassert(false, "partition count is changed (mostly the app was removed and created with the same name), local Vs remote: %u vs %u ",
                            _app_partition_count, resp.partition_count);
                    }
                    _app_id = resp.app_id;
                    _app_partition_count = resp.partition_count;
                    _app_is_stateful = resp.is_stateful;

                    for (auto it = resp.partitions.begin(); it != resp.partitions.end(); ++it)
                    {
                        auto& new_config = *it;

                        dinfo("%s.client: query config reply, gpid = %d.%d, ballot = %" PRId64 ", primary = %s",
                            _app_path.c_str(),
                            new_config.pid.get_app_id(),
                            new_config.pid.get_partition_index(),
                            new_config.ballot,
                            new_config.primary.to_string()
                            );

                        auto it2 = _config_cache.find(new_config.pid.get_partition_index());
                        if (it2 == _config_cache.end())
                        {
                            std::unique_ptr<partition_info> pi(new partition_info);
                            pi->timeout_count = 0;
                            pi->config = new_config;
                            _config_cache.emplace(new_config.pid.get_partition_index(), std::move(pi));
                        }
                        else if (_app_is_stateful && it2->second->config.ballot < new_config.ballot)
                        {
                            it2->second->timeout_count = 0;
                            it2->second->config = new_config;
                        }
                        else if (!_app_is_stateful)
                        {
                            it2->second->timeout_count = 0;
                            it2->second->config = new_config;
                        }
                        else
                        {
                            // nothing to do
                        }
                    }
                }
                else if (resp.err == ERR_OBJECT_NOT_FOUND)
                {
                    derror("%s.client: query config reply, gpid = %d.%d, err = %s",
                        _app_path.c_str(),
                        _app_id,
                        partition_index,
                        resp.err.to_string()
                        );

                    client_err = ERR_APP_NOT_EXIST;
                }
                else
                {
                    derror("%s.client: query config reply, gpid = %d.%d, err = %s",
                        _app_path.c_str(),
                        _app_id,
                        partition_index,
                        resp.err.to_string()
                        );

                    client_err = resp.err;
                }
            }
            else
            {
                derror("%s.client: query config reply, gpid = %d.%d, err = %s",
                    _app_path.c_str(),
                    _app_id,
                    partition_index,
                    err.to_string()
                    );
            }

            // get specific or all partition update
            if (partition_index != -1)
            {
                partition_context* pc = nullptr;
                {
                    zauto_lock l(_requests_lock);
                    auto it = _pending_requests.find(partition_index);
                    if (it != _pending_requests.end())
                    {
                        pc = it->second;
                        _pending_requests.erase(partition_index);
                    }
                }

                if (pc)
                {
                    handle_pending_requests(pc->requests, client_err);
                    delete pc;
                }
            }

            // get all partition update
            else
            {
                pending_replica_requests reqs;
                std::deque<request_context_ptr> reqs2;
                {
                    zauto_lock l(_requests_lock);
                    reqs.swap(_pending_requests);
                    reqs2.swap(_pending_requests_before_partition_count_unknown);
                }
             
                if (!reqs2.empty())
                {
                    if (_app_partition_count != -1)
                    {
                        for (auto& req : reqs2)
                        {
                            dassert(req->partition_index == -1, "");
                            req->partition_index = get_partition_index(_app_partition_count, req->partition_hash);
                        }
                    }
                    handle_pending_requests(reqs2, client_err);
                }

                for (auto& r : reqs)
                {
                    if (r.second)
                    {
                        handle_pending_requests(r.second->requests, client_err);
                        delete r.second;
                    }
                }
            }
        }
コード例 #3
0
void replication_app_client_base::call(request_context_ptr request, bool from_meta_ack)
{
    if (from_meta_ack)
    {
        zauto_lock l(request->lock);
        if (request->completed)
            return;
    }

    auto nts = ::dsn_now_us();

    // timeout will happen very soon, no way to get the rpc call done
    if (nts + 100 >= request->timeout_ts_us) // within 100 us
    {
        dsn_message_t nil(nullptr);
        end_request(request, ERR_TIMEOUT, nil);
        return;
    }

    // calculate timeout
    int timeout_ms;
    if (nts + 1000 > request->timeout_ts_us)
        timeout_ms = 1;
    else
        timeout_ms = static_cast<int>(request->timeout_ts_us - nts) / 1000;

    // fill partition index
    if (_app_partition_count == -1)
    {
        zauto_lock l(_requests_lock);
        query_partition_config(request);
        return;
    }
    else
    {
        request->partition_index = get_partition_index(_app_partition_count, request->key_hash);
    }
    
    // fill target address
    ::dsn::rpc_address addr;
    error_code err = get_address(request->partition_index, !request->is_read, addr, request->read_header.semantic);

    // target address known
    if (err == ERR_OK)
    {
        call_with_address(addr, request);
    }

    // target node not known
    else
    {
        if (from_meta_ack)
        {
            // delay 1 second for further config query, call again
            tasking::enqueue(LPC_REPLICATION_DELAY_QUERY_CONFIG, this,
                std::bind(&replication_app_client_base::call, this, request, false),
                0,
                1000
                );
        }

        else
        {
            // init timeout timer only when necessary
            // DO NOT START THE TIMER FOR EACH REQUEST
            {
                zauto_lock l(request->lock);                
                if (request->timeout_timer == nullptr)
                {
                    request->timeout_timer = tasking::enqueue(
                        LPC_REPLICATION_CLIENT_REQUEST_TIMEOUT,
                        this,
                        std::bind(&replication_app_client_base::on_replica_request_timeout, this, request),
                        0,
                        timeout_ms
                        );
                }
            }

            zauto_lock l(_requests_lock);
            // put into pending queue of querying target partition
            auto it = _pending_replica_requests.find(request->partition_index);
            if (it == _pending_replica_requests.end())
            {
                auto pc = new partition_context;
                pc->query_config_task = nullptr;
                it = _pending_replica_requests.insert(pending_replica_requests::value_type(request->partition_index, pc)).first;
            }

            it->second->requests.push_back(request);
            // init configuration query task if necessary
            if (it->second->query_config_task == nullptr)
            {
                it->second->query_config_task = query_partition_config(request);
            }
        }
    }
}