void partition_resolver_simple::handle_pending_requests(std::deque<request_context_ptr>& reqs, error_code err)
 {
     for (auto& req : reqs)
     {
         if (err == ERR_OK)
         {
             rpc_address addr;
             err = get_address(req->partition_index, addr);
             if (err == ERR_OK)
             {
                 end_request(std::move(req), err, addr);
             }
             else
             {
                 call(std::move(req), true);
             }
         }
         else if (err == ERR_HANDLER_NOT_FOUND)
         {
             end_request(std::move(req), err, rpc_address());
         }
         else
         {
             call(std::move(req), true);
         }
     }
     reqs.clear();
 }
示例#2
0
void docker_scheduler::schedule(
                std::shared_ptr<deployment_unit>& unit
                )
{
    int ret = -1;
    bool found = false;
    {
        zauto_lock l(_lock);
        auto it = _deploy_map.find(unit->name);
        found = (it != _deploy_map.end());
    }
    if ( found )
    {
        unit->deployment_callback(::dsn::dist::ERR_DOCKER_DEPLOY_FAILED,rpc_address());
    }
    else
    {
        //TODO : How about writting machine list failed?
        write_machine_list(unit->name, unit->local_package_directory);
        {
            zauto_lock l(_lock);
            _deploy_map.insert(std::make_pair(unit->name,unit));
        }

        dsn::tasking::enqueue(LPC_DOCKER_CREATE,this, [this, unit]() {
            create_containers(unit->name, unit->deployment_callback, unit->local_package_directory, unit->remote_package_directory);
        });
    }
    
}
示例#3
0
 inline error_code unmarshall_json(const rapidjson::Value &doc, rpc_address& val)
 {
     TEST_PARAM(doc.IsUint64()); 
     dsn_address_t addr;
     addr.u.value = doc.GetUint64();           
     val = rpc_address(addr);
     TEST_PARAM(!val.is_invalid())
     return ERR_OK;
 }
/*search in cache*/
rpc_address partition_resolver_simple::get_address(const partition_configuration &config) const
{
    if (_app_is_stateful) {
        return config.primary;
    } else {
        if (config.last_drops.size() == 0) {
            return rpc_address();
        } else {
            return config.last_drops[rand::next_u32(0, config.last_drops.size() - 1)];
        }
    }
}
示例#5
0
void docker_scheduler::create_containers(std::string& name,std::function<void(error_code, rpc_address)>& deployment_callback, std::string& local_package_directory, std::string& remote_package_directory)
{
    int ret;
    std::ostringstream command;
    command << "./run_docker.sh deploy_and_start ";
    command << " -d " << name << " -s " << local_package_directory;
    if( remote_package_directory == "" )
        command << " -t " << local_package_directory;
    else
        command << " -t " << remote_package_directory;
    ret = system(command.str().c_str());
    if( ret == 0 )
    {
#ifndef _WIN32
        std::string popen_command = "IP=`cat "+ local_package_directory +"/metalist`;echo ${IP#*@}";
        FILE *f = popen(popen_command.c_str(),"r");
        char buffer[30];
        dassert(fgets(buffer,30,f) == buffer, "");
        {
            zauto_lock l(_lock);
            auto unit = _deploy_map[name];
            unit->service_url = buffer;
        }
#endif
        deployment_callback(ERR_OK,rpc_address());
    }
    else
    {
        {
            zauto_lock l(_lock);
            return_machines(name);
            _machine_map.erase(name);
            _deploy_map.erase(name);
        }
        deployment_callback(::dsn::dist::ERR_DOCKER_DEPLOY_FAILED,rpc_address());
    }
}
        /*search in cache*/
        rpc_address partition_resolver_simple::get_address(const partition_configuration& config) const
        {
            if (_app_is_stateful)
            {
                return config.primary;
            }
            else
            {
                if (config.last_drops.size() == 0)
                {
                    return rpc_address();
                }
                else
                {
                    return config.last_drops[dsn_random32(0, config.last_drops.size() - 1)];
                }
            }

            //if (is_write || semantic == read_semantic::ReadLastUpdate)
            //    return config.primary;

            //// readsnapshot or readoutdated, using random
            //else
            //{
            //    bool has_primary = false;
            //    int N = static_cast<int>(config.secondaries.size());
            //    if (!config.primary.is_invalid())
            //    {
            //        N++;
            //        has_primary = true;
            //    }

            //    if (0 == N) return config.primary;

            //    int r = random32(0, 1000) % N;
            //    if (has_primary && r == N - 1)
            //        return config.primary;
            //    else
            //        return config.secondaries[r];
            //}
        }
        void partition_resolver_simple::call(request_context_ptr&& request, bool from_meta_ack)
        {
            int pindex = request->partition_index;
            if (-1 != pindex)
            {
                // fill target address if possible
                rpc_address addr;
                auto err = get_address(pindex, addr);

                // target address known
                if (err == ERR_OK)
                {
                    end_request(std::move(request), ERR_OK, addr);
                    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
            {
                end_request(std::move(request), ERR_TIMEOUT, rpc_address());
                return;
            }

            // delay 1 second for further config query
            if (from_meta_ack)
            {
                tasking::enqueue(
                    LPC_REPLICATION_DELAY_QUERY_CONFIG,
                    this,
                    [=, req2 = request]() mutable
                    {
                        call(std::move(req2), false);
                    },
                    0,
                    std::chrono::seconds(1)
                    );
                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;
            
            // init timeout timer only when necessary
            {
                zauto_lock l(request->lock);
                if (request->timeout_timer == nullptr)
                {
                    request->timeout_timer = tasking::enqueue(
                        LPC_REPLICATION_CLIENT_REQUEST_TIMEOUT,
                        this,
                        [=, req2 = request]() mutable
                        {
                            on_timeout(std::move(req2));
                        },
                        0,
                        std::chrono::milliseconds(timeout_ms)
                        );
                }
            }

            {
                zauto_lock l(_requests_lock);
                if (-1 != pindex)
                {
                    // put into pending queue of querying target partition
                    auto it = _pending_requests.find(pindex);
                    if (it == _pending_requests.end())
                    {
                        auto pc = new partition_context();
                        it = _pending_requests.emplace(pindex, pc).first;
                    }
                    it->second->requests.push_back(std::move(request));

                    // init configuration query task if necessary
                    if (nullptr == it->second->query_config_task)
                    {
                        it->second->query_config_task = query_config(pindex);
                    }
                }
                else
                {
                    _pending_requests_before_partition_count_unknown.push_back(std::move(request));
                    if (_pending_requests_before_partition_count_unknown.size() == 1)
                    {
                        _query_config_task = query_config(pindex);
                    }
                }
            }
        }
 void partition_resolver_simple::on_timeout(request_context_ptr&& rc) const
 {
     end_request(std::move(rc), ERR_TIMEOUT, rpc_address(), true);
 }