diff options
Diffstat (limited to 'indra/llmessage/llexperiencecache.cpp')
-rw-r--r-- | indra/llmessage/llexperiencecache.cpp | 363 |
1 files changed, 358 insertions, 5 deletions
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index 36a4fc8823..92fcd38d3b 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -26,7 +26,6 @@ #include "llexperiencecache.h" #include "llavatarname.h" -#include "llhttpclient.h" #include "llsdserialize.h" #include "llcoros.h" #include "lleventcoro.h" @@ -84,6 +83,7 @@ const int LLExperienceCache::PROPERTY_SUSPENDED = 1 << 7; // default values const F64 LLExperienceCache::DEFAULT_EXPIRATION = 600.0; const S32 LLExperienceCache::DEFAULT_QUOTA = 128; // this is megabytes +const int LLExperienceCache::SEARCH_PAGE_SIZE = 30; //========================================================================= LLExperienceCache::LLExperienceCache(): @@ -248,7 +248,7 @@ void LLExperienceCache::requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdap //LL_INFOS("requestExperiencesCoro") << "url: " << url << LL_ENDL; - LLSD result = httpAdapter->getAndYield(httpRequest, url); + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); @@ -356,7 +356,7 @@ void LLExperienceCache::requestExperiences() if (mRequestQueue.empty() || (ostr.tellp() > EXP_URL_SEND_THRESHOLD)) { // request is placed in the coprocedure pool for the ExpCache cache. Throttling is done by the pool itself. - LLCoprocedureManager::getInstance()->enqueueCoprocedure("ExpCache", "Request", + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "RequestExperiences", boost::bind(&LLExperienceCache::requestExperiencesCoro, this, _1, ostr.str(), requests) ); ostr.str(std::string()); @@ -401,7 +401,7 @@ void LLExperienceCache::idleCoro() do { timeout.eventAfter(SECS_BETWEEN_REQUESTS, LLSD()); - llcoro::waitForEventOn(timeout); + llcoro::suspendUntilEventOn(timeout); if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT)) { @@ -506,7 +506,8 @@ const LLSD& LLExperienceCache::get(const LLUUID& key) return empty; } -void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::Callback_t slot) + +void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::ExperienceGetFn_t slot) { if(key.isNull()) return; @@ -533,6 +534,358 @@ void LLExperienceCache::get(const LLUUID& key, LLExperienceCache::Callback_t slo } //========================================================================= +void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated", + boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, fn)); +} + +void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + std::string url = mCapability("GetMetadata"); + + if (url.empty()) + { + LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL; + return; + } + + LLSD fields; + fields.append("experience"); + LLSD data; + data["object-id"] = objectId; + data["item-id"] = itemId; + data["fields"] = fields; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, data); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if ((!status) || (!result.has("experience"))) + { + LLSD failure; + if (!status) + { + failure["error"] = (LLSD::Integer)status.getType(); + failure["message"] = status.getMessage(); + } + else + { + failure["error"] = -1; + failure["message"] = "no experience"; + } + if (fn && !fn.empty()) + fn(failure); + return; + } + + LLUUID expId = result["experience"].asUUID(); + get(expId, fn); +} + +//------------------------------------------------------------------------- +void LLExperienceCache::findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Search Name", + boost::bind(&LLExperienceCache::findExperienceByNameCoro, this, _1, text, page, fn)); +} + +void LLExperienceCache::findExperienceByNameCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, std::string text, int page, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + std::ostringstream url; + + + url << mCapability("FindExperienceByName") << "?page=" << page << "&page_size=" << SEARCH_PAGE_SIZE << "&query=" << LLURI::escape(text); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url.str()); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + fn(LLSD()); + return; + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + + const LLSD& experiences = result["experience_keys"]; + for (LLSD::array_const_iterator it = experiences.beginArray(); it != experiences.endArray(); ++it) + { + insert(*it); + } + + fn(result); +} + +//------------------------------------------------------------------------- +void LLExperienceCache::getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Group Experiences", + boost::bind(&LLExperienceCache::getGroupExperiencesCoro, this, _1, groupId, fn)); +} + +void LLExperienceCache::getGroupExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID groupId, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + // search for experiences owned by the current group + std::string url = mCapability("GroupExperiences"); + if (url.empty()) + { + LL_WARNS("ExperienceCache") << "No Group Experiences capability" << LL_ENDL; + return; + } + + url += "?" + groupId.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + fn(LLSD()); + return; + } + + const LLSD& experienceIds = result["experience_ids"]; + fn(experienceIds); +} + +//------------------------------------------------------------------------- +void LLExperienceCache::getRegionExperiences(CapabilityQuery_t regioncaps, ExperienceGetFn_t fn) +{ + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Region Experiences", + boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, regioncaps, false, LLSD(), fn)); +} + +void LLExperienceCache::setRegionExperiences(CapabilityQuery_t regioncaps, const LLSD &experiences, ExperienceGetFn_t fn) +{ + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Region Experiences", + boost::bind(&LLExperienceCache::regionExperiencesCoro, this, _1, regioncaps, true, experiences, fn)); +} + +void LLExperienceCache::regionExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, + CapabilityQuery_t regioncaps, bool update, LLSD experiences, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + // search for experiences owned by the current group + std::string url = regioncaps("RegionExperiences"); + if (url.empty()) + { + LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL; + return; + } + + LLSD result; + if (update) + result = httpAdapter->postAndSuspend(httpRequest, url, experiences); + else + result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { +// fn(LLSD()); + return; + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + fn(result); + +} + +//------------------------------------------------------------------------- +void LLExperienceCache::getExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString(); + + permissionInvoker_fn invoker(boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, LLCore::HttpOptions::ptr_t(), LLCore::HttpHeaders::ptr_t())); + + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Preferences Set", + boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, invoker, url, fn)); +} + +void LLExperienceCache::setExperiencePermission(const LLUUID &experienceId, const std::string &permission, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + std::string url = mCapability("ExperiencePreferences"); + if (url.empty()) + return; + LLSD permData; + LLSD data; + permData["permission"] = permission; + data[experienceId.asString()] = permData; + + permissionInvoker_fn invoker(boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, const LLSD &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + (&LLCoreHttpUtil::HttpCoroutineAdapter::putAndSuspend), _1, _2, _3, data, LLCore::HttpOptions::ptr_t(), LLCore::HttpHeaders::ptr_t())); + + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Preferences Set", + boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, invoker, url, fn)); +} + +void LLExperienceCache::forgetExperiencePermission(const LLUUID &experienceId, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + std::string url = mCapability("ExperiencePreferences") + "?" + experienceId.asString(); + + + permissionInvoker_fn invoker(boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)> + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + (&LLCoreHttpUtil::HttpCoroutineAdapter::deleteAndSuspend), _1, _2, _3, LLCore::HttpOptions::ptr_t(), LLCore::HttpHeaders::ptr_t())); + + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Preferences Set", + boost::bind(&LLExperienceCache::experiencePermissionCoro, this, _1, invoker, url, fn)); +} + +void LLExperienceCache::experiencePermissionCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, permissionInvoker_fn invokerfn, std::string url, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + // search for experiences owned by the current group + + LLSD result = invokerfn(httpAdapter, httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + + if (status) + { + fn(result); + } +} + +//------------------------------------------------------------------------- +void LLExperienceCache::getExperienceAdmin(const LLUUID &experienceId, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "IsAdmin", + boost::bind(&LLExperienceCache::getExperienceAdminCoro, this, _1, experienceId, fn)); +} + +void LLExperienceCache::getExperienceAdminCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID experienceId, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + std::string url = mCapability("IsExperienceAdmin"); + if (url.empty()) + { + LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL; + return; + } + url += "?experience_id=" + experienceId.asString(); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); +// LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; +// LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + fn(result); +} + +//------------------------------------------------------------------------- +void LLExperienceCache::updateExperience(LLSD updateData, ExperienceGetFn_t fn) +{ + if (mCapability.empty()) + { + LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL; + return; + } + + LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "IsAdmin", + boost::bind(&LLExperienceCache::updateExperienceCoro, this, _1, updateData, fn)); +} + +void LLExperienceCache::updateExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLSD updateData, ExperienceGetFn_t fn) +{ + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); + + std::string url = mCapability("UpdateExperience"); + if (url.empty()) + { + LL_WARNS("ExperienceCache") << "No Region Experiences capability" << LL_ENDL; + return; + } + + updateData.erase(LLExperienceCache::QUOTA); + updateData.erase(LLExperienceCache::EXPIRES); + updateData.erase(LLExperienceCache::AGENT_ID); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, updateData); + + fn(result); +} + +//========================================================================= void LLExperienceCacheImpl::mapKeys(const LLSD& legacyKeys) { LLSD::array_const_iterator exp = legacyKeys.beginArray(); |