示例#1
0
文件: mutation.cpp 项目: ykwd/rDSN
void mutation::copy_from(mutation_ptr& old)
{
    data.updates = old->data.updates;
    client_requests = old->client_requests;
    _appro_data_bytes = old->_appro_data_bytes;
    _create_ts_ns = old->_create_ts_ns;

    for (auto& r : client_requests)
    {
        if (r != nullptr)
        {
            dsn_msg_add_ref(r); // release in dctor
        }
    }

    // let's always re-append the mutation to 
    // replication logs as the ballot number
    // is changed, to ensure the invariance:
    // if decree(A) >= decree(B) 
    // then ballot(A) >= ballot(B)
    /*if (old->is_logged())
    {
        set_logged();
        data.header.log_offset = old->data.header.log_offset;
    }
    */

    _prepare_request = old->prepare_msg();
    if (_prepare_request)
    {
        dsn_msg_add_ref(_prepare_request);
    }
}
示例#2
0
/*static*/ mutation_ptr mutation::read_from(binary_reader& reader, dsn_message_t from)
{
    mutation_ptr mu(new mutation());
    unmarshall(reader, mu->data);
    unmarshall(reader, mu->rpc_code);

    // it is possible this is an emtpy mutation due to new primaries inserts empty mutations for holes
    dassert(mu->data.updates.size() == 1 || mu->rpc_code == RPC_REPLICATION_WRITE_EMPTY,
        "batch is not supported now");

    if (nullptr != from)
    {
        mu->_prepare_request = from;
        dsn_msg_add_ref(from); // released on dctor
    }
    else if (mu->data.updates.size() > 0)
    {
        dassert(mu->data.updates.at(0).has_holder(), 
            "the buffer must has ownership");
    }
    else
    {
        dassert(mu->rpc_code == RPC_REPLICATION_WRITE_EMPTY, "must be RPC_REPLICATION_WRITE_EMPTY");
    }
    
    sprintf(mu->_name, "%lld.%lld",
        static_cast<long long int>(mu->data.header.ballot),
        static_cast<long long int>(mu->data.header.decree));

    return mu;
}
示例#3
0
文件: mutation.cpp 项目: ykwd/rDSN
/*static*/ mutation_ptr mutation::read_from(binary_reader& reader, dsn_message_t from)
{
    mutation_ptr mu(new mutation());
    unmarshall(reader, mu->data, DSF_THRIFT_BINARY);

    for (const mutation_update& update : mu->data.updates)
    {
        dassert(update.code != TASK_CODE_INVALID, "invalid mutation task code");
    }

    mu->client_requests.resize(mu->data.updates.size());

    if (nullptr != from)
    {
        mu->_prepare_request = from;
        dsn_msg_add_ref(from); // released on dctor
    }
    
    snprintf_p(mu->_name, sizeof(mu->_name),
        "%" PRId32 ".%" PRId32 ".%" PRId64 ".%" PRId64,
        mu->data.header.pid.get_app_id(),
        mu->data.header.pid.get_partition_index(),
        mu->data.header.ballot,
        mu->data.header.decree);

    return mu;
}
示例#4
0
文件: mutation.cpp 项目: ykwd/rDSN
void mutation::add_client_request(task_code code, dsn_message_t request)
{
    data.updates.push_back(mutation_update());
    mutation_update& update = data.updates.back();
    _appro_data_bytes += 32; // approximate code size

    if (request != nullptr)
    {
        update.code = code;
        dsn_msg_add_ref(request); // released on dctor

        void* ptr;
        size_t size;
        bool r = dsn_msg_read_next(request, &ptr, &size);
        dassert(r, "payload is not present");
        dsn_msg_read_commit(request, 0); // so we can re-read the request buffer in replicated app
        update.data.assign((char*)ptr, 0, (int)size);

        _appro_data_bytes += sizeof(int) + (int)size; // data size
    }   
    else
    {
        update.code = RPC_REPLICATION_WRITE_EMPTY;
        _appro_data_bytes += sizeof(int); // empty data size
    }

    client_requests.push_back(request);

    dassert(client_requests.size() == data.updates.size(), "size must be equal");
}
示例#5
0
void mutation::copy_from(mutation_ptr& old)
{
    data.updates = old->data.updates;
    rpc_code = old->rpc_code;
    if (old->is_logged())
    {
        set_logged();
        data.header.log_offset = old->data.header.log_offset;
    }
        
    _client_request = old->client_msg();
    if (_client_request)
    {
        dsn_msg_add_ref(_client_request);
    }

    _prepare_request = old->prepare_msg();
    if (_prepare_request)
    {
        dsn_msg_add_ref(_prepare_request);
    }
}
示例#6
0
void mutation::set_client_request(dsn_task_code_t code, dsn_message_t request)
{
    dassert(_client_request == nullptr, "batch is not supported now");
    rpc_code = code;

    if (request != nullptr)
    {
        _client_request = request;
        dsn_msg_add_ref(request); // released on dctor

        void* ptr;
        size_t size;
        bool r = dsn_msg_read_next(request, &ptr, &size);
        dassert(r, "payload is not present");
        dsn_msg_read_commit(request, size);

        blob buffer((char*)ptr, 0, (int)size);
        data.updates.push_back(buffer);
    }    
}
示例#7
0
文件: mutation.cpp 项目: ykwd/rDSN
/*static*/ mutation_ptr mutation::read_from_log_file(binary_reader& reader, dsn_message_t from)
{
    mutation_ptr mu(new mutation());
    unmarshall(reader, mu->data.header, DSF_THRIFT_BINARY);
    int size;
    unmarshall(reader, size, DSF_THRIFT_BINARY);
    mu->data.updates.resize(size);
    std::vector<int> lengths(size, 0);
    for (int i = 0; i < size; ++i)
    {
        unmarshall(reader, mu->data.updates[i].code, DSF_THRIFT_BINARY);
        unmarshall(reader, lengths[i], DSF_THRIFT_BINARY);
    }
    for (int i = 0; i < size; ++i)
    {
        int len = lengths[i];
        std::shared_ptr<char> holder(new char[len], [](char* ptr){ delete []ptr; });
        reader.read(holder.get(), len);
        mu->data.updates[i].data.assign(holder, 0, len);
    }

    mu->client_requests.resize(mu->data.updates.size());

    if (nullptr != from)
    {
        mu->_prepare_request = from;
        dsn_msg_add_ref(from); // released on dctor
    }

    snprintf_p(mu->_name, sizeof(mu->_name),
        "%" PRId32 ".%" PRId32 ".%" PRId64 ".%" PRId64,
        mu->data.header.pid.get_app_id(),
        mu->data.header.pid.get_partition_index(),
        mu->data.header.ballot,
        mu->data.header.decree);

    return mu;
}
示例#8
0
void replica::on_update_configuration_on_meta_server_reply(error_code err, dsn_message_t request, dsn_message_t response, std::shared_ptr<configuration_update_request> req)
{
    check_hashed_access();

    if (PS_INACTIVE != status() || _stub->is_connected() == false)
    {
        _primary_states.reconfiguration_task = nullptr;
        err.end_tracking();
        return;
    }

    configuration_update_response resp;
    if (err == ERR_OK)
    {
        ::unmarshall(response, resp);
        err = resp.err;
    }

    if (err != ERR_OK)
    {
        ddebug(
            "%s: update configuration reply with err %s, request ballot %lld",
            name(),
            err.to_string(),
            req->config.ballot
            );

        if (err != ERR_INVALID_VERSION)
        {
            rpc_address target(_stub->_failure_detector->get_servers());
            dsn_msg_add_ref(request); // added for another round of rpc::call
            _primary_states.reconfiguration_task = rpc::call(
                target,
                request,
                this,
                std::bind(&replica::on_update_configuration_on_meta_server_reply, this,
                std::placeholders::_1,
                std::placeholders::_2,
                std::placeholders::_3,
                req),
                gpid_to_hash(get_gpid())
                );
            return;
        }        
    }

    ddebug(
        "%s: update configuration reply with err %s, ballot %lld, local %lld",
        name(),
        resp.err.to_string(),
        resp.config.ballot,
        get_ballot()
        );
    
    if (resp.config.ballot < get_ballot())
    {
        _primary_states.reconfiguration_task = nullptr;
        return;
    }        
    
    // post-update work items?
    if (resp.err == ERR_OK)
    {        
        dassert (req->config.gpid == resp.config.gpid, "");
        dassert (req->config.app_type == resp.config.app_type, "");
        dassert (req->config.primary == resp.config.primary, "");
        dassert (req->config.secondaries == resp.config.secondaries, "");

        switch (req->type)
        {        
        case CT_UPGRADE_TO_PRIMARY:
            _primary_states.last_prepare_decree_on_new_primary = _prepare_list->max_decree();
            break;
        case CT_ASSIGN_PRIMARY:
        case CT_DOWNGRADE_TO_SECONDARY:
        case CT_DOWNGRADE_TO_INACTIVE:
        case CT_UPGRADE_TO_SECONDARY:
            break;
        case CT_REMOVE:
            if (req->node != primary_address())
            {
                replica_configuration rconfig;
                replica_helper::get_replica_config(resp.config, req->node, rconfig);
                rpc::call_one_way_typed(req->node, RPC_REMOVE_REPLICA, rconfig, gpid_to_hash(get_gpid()));
            }
            break;
        default:
            dassert (false, "");
        }
    }
    
    update_configuration(resp.config);
    _primary_states.reconfiguration_task = nullptr;
}