summaryrefslogtreecommitdiff
path: root/indra/llmessage/llexperiencecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llexperiencecache.cpp')
-rw-r--r--indra/llmessage/llexperiencecache.cpp363
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();