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(); }
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); }); } }
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)]; } } }
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); }