DRTVWR-493 LLAvatarNameCache to singletone

master
andreykproductengine 2019-07-03 20:06:47 +03:00
parent 2752e342f6
commit 779b5627c5
13 changed files with 221 additions and 203 deletions

View File

@ -49,101 +49,22 @@
#include <map>
#include <set>
namespace LLAvatarNameCache
{
use_display_name_signal_t mUseDisplayNamesSignal;
// Cache starts in a paused state until we can determine if the
// current region supports display names.
bool sRunning = false;
// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
bool sUsePeopleAPI = true;
// Base lookup URL for name service.
// On simulator, loaded from indra.xml
// On viewer, usually a simulator capability (at People API team's request)
// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
std::string sNameLookupURL;
// Time-to-live for a temp cache entry.
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
// Maximum time an unrefreshed cache entry is allowed.
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
// Accumulated agent IDs for next query against service
typedef std::set<LLUUID> ask_queue_t;
ask_queue_t sAskQueue;
// Send bulk lookup requests a few times a second at most.
// Only need per-frame timing resolution.
static LLFrameTimer sRequestTimer;
// Agent IDs that have been requested, but with no reply.
// Maps agent ID to frame time request was made.
typedef std::map<LLUUID, F64> pending_queue_t;
pending_queue_t sPendingQueue;
// Callbacks to fire when we received a name.
// May have multiple callbacks for a single ID, which are
// represented as multiple slots bound to the signal.
// Avoid copying signals via pointers.
typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
signal_map_t sSignalMap;
// The cache at last, i.e. avatar names we know about.
typedef std::map<LLUUID, LLAvatarName> cache_t;
cache_t sCache;
// Send bulk lookup requests a few times a second at most.
// Only need per-frame timing resolution.
LLFrameTimer sRequestTimer;
// Maximum time an unrefreshed cache entry is allowed.
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
// Time when unrefreshed cached names were checked last.
static F64 sLastExpireCheck;
// Time-to-live for a temp cache entry.
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
LLCore::HttpRequest::ptr_t sHttpRequest;
LLCore::HttpHeaders::ptr_t sHttpHeaders;
LLCore::HttpOptions::ptr_t sHttpOptions;
LLCore::HttpRequest::policy_t sHttpPolicy;
LLCore::HttpRequest::priority_t sHttpPriority;
//-----------------------------------------------------------------------
// Internal methods
//-----------------------------------------------------------------------
// Handle name response off network.
void processName(const LLUUID& agent_id,
const LLAvatarName& av_name);
void requestNamesViaCapability();
// Legacy name system callbacks
void legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group);
void legacyNameFetch(const LLUUID& agent_id,
const std::string& full_name,
bool is_group);
void requestNamesViaLegacy();
// Do a single callback to a given slot
void fireSignal(const LLUUID& agent_id,
const callback_slot_t& slot,
const LLAvatarName& av_name);
// Is a request in-flight over the network?
bool isRequestPending(const LLUUID& agent_id);
// Erase expired names from cache
void eraseUnrefreshed();
bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
// This is a coroutine.
void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds);
void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
}
// static to avoid unnessesary dependencies
LLCore::HttpRequest::ptr_t sHttpRequest;
LLCore::HttpHeaders::ptr_t sHttpHeaders;
LLCore::HttpOptions::ptr_t sHttpOptions;
LLCore::HttpRequest::policy_t sHttpPolicy;
LLCore::HttpRequest::priority_t sHttpPriority;
/* Sample response:
<?xml version="1.0"?>
@ -187,6 +108,30 @@ namespace LLAvatarNameCache
// Coroutine for sending and processing avatar name cache requests.
// Do not call directly. See documentation in lleventcoro.h and llcoro.h for
// further explanation.
LLAvatarNameCache::LLAvatarNameCache()
{
// Will be set to running later
// For now fail immediate lookups and query async ones.
mRunning = false;
mUsePeopleAPI = true;
sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
sHttpPriority = 0;
}
LLAvatarNameCache::~LLAvatarNameCache()
{
sHttpRequest.reset();
sHttpHeaders.reset();
sHttpOptions.reset();
mCache.clear();
}
void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds)
{
LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName()
@ -205,7 +150,7 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
{
bool success = true;
LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy);
LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);
LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);
LL_DEBUGS() << results << LL_ENDL;
@ -233,12 +178,12 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
for ( ; it != agentIds.end(); ++it)
{
const LLUUID& agent_id = *it;
LLAvatarNameCache::handleAgentError(agent_id);
LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
}
return;
}
LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults);
LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
}
catch (...)
@ -300,15 +245,15 @@ void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &h
}
}
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result "
<< LLAvatarNameCache::sCache.size() << " cached names"
<< LLAvatarNameCache::mCache.size() << " cached names"
<< LL_ENDL;
}
// Provide some fallback for agents that return errors
void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
{
std::map<LLUUID,LLAvatarName>::iterator existing = sCache.find(agent_id);
if (existing == sCache.end())
std::map<LLUUID,LLAvatarName>::iterator existing = mCache.find(agent_id);
if (existing == mCache.end())
{
// there is no existing cache entry, so make a temporary name from legacy
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
@ -322,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
// been returned by the get method, there is no need to signal anyone
// Clear this agent from the pending list
LLAvatarNameCache::sPendingQueue.erase(agent_id);
LLAvatarNameCache::mPendingQueue.erase(agent_id);
LLAvatarName& av_name = existing->second;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
@ -341,19 +286,19 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
}
// Add to the cache
sCache[agent_id] = av_name;
mCache[agent_id] = av_name;
// Suppress request from the queue
sPendingQueue.erase(agent_id);
mPendingQueue.erase(agent_id);
// Signal everyone waiting on this name
signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
if (sig_it != sSignalMap.end())
signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
if (sig_it != mSignalMap.end())
{
callback_signal_t* signal = sig_it->second;
(*signal)(agent_id, av_name);
sSignalMap.erase(agent_id);
mSignalMap.erase(agent_id);
delete signal;
signal = NULL;
@ -379,16 +324,16 @@ void LLAvatarNameCache::requestNamesViaCapability()
U32 ids = 0;
ask_queue_t::const_iterator it;
while(!sAskQueue.empty())
while(!mAskQueue.empty())
{
it = sAskQueue.begin();
it = mAskQueue.begin();
LLUUID agent_id = *it;
sAskQueue.erase(it);
mAskQueue.erase(it);
if (url.empty())
{
// ...starting new request
url += sNameLookupURL;
url += mNameLookupURL;
url += "?ids=";
ids = 1;
}
@ -402,7 +347,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
agent_ids.push_back(agent_id);
// mark request as pending
sPendingQueue[agent_id] = now;
mPendingQueue[agent_id] = now;
if (url.size() > NAME_URL_SEND_THRESHOLD)
{
@ -432,7 +377,7 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
// protocol, we do not get an expiration date for each name and there's no reason to ask the
// data again and again so we set the expiration time to the largest value admissible.
std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
std::map<LLUUID,LLAvatarName>::iterator av_record = LLAvatarNameCache::getInstance()->mCache.find(agent_id);
LLAvatarName& av_name = av_record->second;
av_name.setExpires(MAX_UNREFRESHED_TIME);
}
@ -451,7 +396,7 @@ void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
av_name.fromString(full_name);
// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
processName(agent_id, av_name);
LLAvatarNameCache::getInstance()->processName(agent_id, av_name);
}
void LLAvatarNameCache::requestNamesViaLegacy()
@ -460,15 +405,15 @@ void LLAvatarNameCache::requestNamesViaLegacy()
F64 now = LLFrameTimer::getTotalSeconds();
std::string full_name;
ask_queue_t::const_iterator it;
for (S32 requests = 0; !sAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
for (S32 requests = 0; !mAskQueue.empty() && requests < MAX_REQUESTS; ++requests)
{
it = sAskQueue.begin();
it = mAskQueue.begin();
LLUUID agent_id = *it;
sAskQueue.erase(it);
mAskQueue.erase(it);
// Mark as pending first, just in case the callback is immediately
// invoked below. This should never happen in practice.
sPendingQueue[agent_id] = now;
mPendingQueue[agent_id] = now;
LL_DEBUGS("AvNameCache") << "agent " << agent_id << LL_ENDL;
@ -477,26 +422,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
}
}
void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
{
sRunning = running;
sUsePeopleAPI = usePeopleAPI;
sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders());
sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions());
sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
sHttpPriority = 0;
}
void LLAvatarNameCache::cleanupClass()
{
sHttpRequest.reset();
sHttpHeaders.reset();
sHttpOptions.reset();
sCache.clear();
}
bool LLAvatarNameCache::importFile(std::istream& istr)
{
LLSD data;
@ -517,9 +442,9 @@ bool LLAvatarNameCache::importFile(std::istream& istr)
{
agent_id.set(it->first);
av_name.fromLLSD( it->second );
sCache[agent_id] = av_name;
mCache[agent_id] = av_name;
}
LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << sCache.size() << LL_ENDL;
LL_INFOS("AvNameCache") << "LLAvatarNameCache loaded " << mCache.size() << LL_ENDL;
// Some entries may have expired since the cache was stored,
// but they will be flushed in the first call to eraseUnrefreshed
// from LLAvatarNameResponder::idle
@ -531,9 +456,9 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
{
LLSD agents;
F64 max_unrefreshed = LLFrameTimer::getTotalSeconds() - MAX_UNREFRESHED_TIME;
LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << sCache.size() << LL_ENDL;
cache_t::const_iterator it = sCache.begin();
for ( ; it != sCache.end(); ++it)
LL_INFOS("AvNameCache") << "LLAvatarNameCache at exit cache has " << mCache.size() << LL_ENDL;
cache_t::const_iterator it = mCache.begin();
for ( ; it != mCache.end(); ++it)
{
const LLUUID& agent_id = it->first;
const LLAvatarName& av_name = it->second;
@ -552,23 +477,28 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url)
{
sNameLookupURL = name_lookup_url;
mNameLookupURL = name_lookup_url;
}
bool LLAvatarNameCache::hasNameLookupURL()
{
return !sNameLookupURL.empty();
return !mNameLookupURL.empty();
}
void LLAvatarNameCache::setUsePeopleAPI(bool use_api)
{
mUsePeopleAPI = use_api;
}
bool LLAvatarNameCache::usePeopleAPI()
{
return hasNameLookupURL() && sUsePeopleAPI;
return hasNameLookupURL() && mUsePeopleAPI;
}
void LLAvatarNameCache::idle()
{
// By convention, start running at first idle() call
sRunning = true;
mRunning = true;
// *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can
@ -579,7 +509,7 @@ void LLAvatarNameCache::idle()
return;
}
if (!sAskQueue.empty())
if (!mAskQueue.empty())
{
if (usePeopleAPI())
{
@ -592,7 +522,7 @@ void LLAvatarNameCache::idle()
}
}
if (sAskQueue.empty())
if (mAskQueue.empty())
{
// cleared the list, reset the request timer.
sRequestTimer.resetWithExpiry(SECS_BETWEEN_REQUESTS);
@ -607,8 +537,8 @@ bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id)
bool isPending = false;
const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0;
pending_queue_t::const_iterator it = sPendingQueue.find(agent_id);
if (it != sPendingQueue.end())
pending_queue_t::const_iterator it = mPendingQueue.find(agent_id);
if (it != mPendingQueue.end())
{
// in the list of requests in flight, retry if too old
F64 expire_time = LLFrameTimer::getTotalSeconds() - PENDING_TIMEOUT_SECS;
@ -622,11 +552,11 @@ void LLAvatarNameCache::eraseUnrefreshed()
F64 now = LLFrameTimer::getTotalSeconds();
F64 max_unrefreshed = now - MAX_UNREFRESHED_TIME;
if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed)
if (!mLastExpireCheck || mLastExpireCheck < max_unrefreshed)
{
sLastExpireCheck = now;
mLastExpireCheck = now;
S32 expired = 0;
for (cache_t::iterator it = sCache.begin(); it != sCache.end();)
for (cache_t::iterator it = mCache.begin(); it != mCache.end();)
{
const LLAvatarName& av_name = it->second;
if (av_name.mExpires < max_unrefreshed)
@ -635,7 +565,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
<< " user '" << av_name.getAccountName() << "' "
<< "expired " << now - av_name.mExpires << " secs ago"
<< LL_ENDL;
sCache.erase(it++);
mCache.erase(it++);
expired++;
}
else
@ -644,19 +574,24 @@ void LLAvatarNameCache::eraseUnrefreshed()
}
}
LL_INFOS("AvNameCache") << "LLAvatarNameCache expired " << expired << " cached avatar names, "
<< sCache.size() << " remaining" << LL_ENDL;
<< mCache.size() << " remaining" << LL_ENDL;
}
}
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
// returns bool specifying if av_name was filled, false otherwise
//static, wrapper
bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
{
if (sRunning)
return LLAvatarNameCache::getInstance()->getName(agent_id, av_name);
}
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
// returns bool specifying if av_name was filled, false otherwise
bool LLAvatarNameCache::getName(const LLUUID& agent_id, LLAvatarName *av_name)
{
if (mRunning)
{
// ...only do immediate lookups when cache is running
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
if (it != sCache.end())
std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
if (it != mCache.end())
{
*av_name = it->second;
@ -667,7 +602,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache refresh agent " << agent_id
<< LL_ENDL;
sAskQueue.insert(agent_id);
mAskQueue.insert(agent_id);
}
}
@ -678,7 +613,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
if (!isRequestPending(agent_id))
{
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache queue request for agent " << agent_id << LL_ENDL;
sAskQueue.insert(agent_id);
mAskQueue.insert(agent_id);
}
return false;
@ -693,15 +628,21 @@ void LLAvatarNameCache::fireSignal(const LLUUID& agent_id,
signal(agent_id, av_name);
}
// static, wrapper
LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
return LLAvatarNameCache::getInstance()->getNameCallback(agent_id, slot);
}
LLAvatarNameCache::callback_connection_t LLAvatarNameCache::getNameCallback(const LLUUID& agent_id, callback_slot_t slot)
{
callback_connection_t connection;
if (sRunning)
if (mRunning)
{
// ...only do immediate lookups when cache is running
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
if (it != sCache.end())
std::map<LLUUID,LLAvatarName>::iterator it = mCache.find(agent_id);
if (it != mCache.end())
{
const LLAvatarName& av_name = it->second;
@ -717,17 +658,17 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
// schedule a request
if (!isRequestPending(agent_id))
{
sAskQueue.insert(agent_id);
mAskQueue.insert(agent_id);
}
// always store additional callback, even if request is pending
signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
if (sig_it == sSignalMap.end())
signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
if (sig_it == mSignalMap.end())
{
// ...new callback for this id
callback_signal_t* signal = new callback_signal_t();
connection = signal->connect(slot);
sSignalMap[agent_id] = signal;
mSignalMap[agent_id] = signal;
}
else
{
@ -760,20 +701,20 @@ void LLAvatarNameCache::setUseUsernames(bool use)
void LLAvatarNameCache::erase(const LLUUID& agent_id)
{
sCache.erase(agent_id);
mCache.erase(agent_id);
}
void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name)
{
// *TODO: update timestamp if zero?
sCache[agent_id] = av_name;
mCache[agent_id] = av_name;
}
LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
{
std::map<LLUUID, LLAvatarName>::iterator it;
std::map<LLUUID, LLAvatarName>::iterator end = sCache.end();
for (it = sCache.begin(); it != end; ++it)
std::map<LLUUID, LLAvatarName>::iterator end = mCache.end();
for (it = mCache.begin(); it != end; ++it)
{
if (it->second.getUserName() == name)
{

View File

@ -29,21 +29,20 @@
#define LLAVATARNAMECACHE_H
#include "llavatarname.h" // for convenience
#include "llsingleton.h"
#include <boost/signals2.hpp>
#include <set>
class LLSD;
class LLUUID;
namespace LLAvatarNameCache
class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>
{
LLSINGLETON(LLAvatarNameCache);
~LLAvatarNameCache();
public:
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
// Until the cache is set running, immediate lookups will fail and
// async lookups will be queued. This allows us to block requests
// until we know if the first region supports display names.
void initClass(bool running, bool usePeopleAPI);
void cleanupClass();
// Import/export the name cache to file.
bool importFile(std::istream& istr);
void exportFile(std::ostream& ostr);
@ -55,6 +54,7 @@ namespace LLAvatarNameCache
// Do we have a valid lookup URL, i.e. are we trying to use the
// more recent display name lookup system?
bool hasNameLookupURL();
void setUsePeopleAPI(bool use_api);
bool usePeopleAPI();
// Periodically makes a batch request for display names not already in
@ -63,7 +63,8 @@ namespace LLAvatarNameCache
// If name is in cache, returns true and fills in provided LLAvatarName
// otherwise returns false.
bool get(const LLUUID& agent_id, LLAvatarName *av_name);
static bool get(const LLUUID& agent_id, LLAvatarName *av_name);
bool getName(const LLUUID& agent_id, LLAvatarName *av_name);
// Callback types for get() below
typedef boost::signals2::signal<
@ -74,7 +75,8 @@ namespace LLAvatarNameCache
// Fetches name information and calls callbacks.
// If name information is in cache, callbacks will be called immediately.
callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
static callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
callback_connection_t getNameCallback(const LLUUID& agent_id, callback_slot_t slot);
// Set display name: flips the switch and triggers the callbacks.
void setUseDisplayNames(bool use);
@ -100,7 +102,83 @@ namespace LLAvatarNameCache
F64 nameExpirationFromHeaders(const LLSD& headers);
void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
}
private:
// Handle name response off network.
void processName(const LLUUID& agent_id,
const LLAvatarName& av_name);
void requestNamesViaCapability();
// Legacy name system callbacks
static void legacyNameCallback(const LLUUID& agent_id,
const std::string& full_name,
bool is_group);
static void legacyNameFetch(const LLUUID& agent_id,
const std::string& full_name,
bool is_group);
void requestNamesViaLegacy();
// Do a single callback to a given slot
void fireSignal(const LLUUID& agent_id,
const callback_slot_t& slot,
const LLAvatarName& av_name);
// Is a request in-flight over the network?
bool isRequestPending(const LLUUID& agent_id);
// Erase expired names from cache
void eraseUnrefreshed();
bool expirationFromCacheControl(const LLSD& headers, F64 *expires);
// This is a coroutine.
static void requestAvatarNameCache_(std::string url, std::vector<LLUUID> agentIds);
void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult);
private:
use_display_name_signal_t mUseDisplayNamesSignal;
// Cache starts in a paused state until we can determine if the
// current region supports display names.
bool mRunning;
// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
bool mUsePeopleAPI;
// Base lookup URL for name service.
// On simulator, loaded from indra.xml
// On viewer, usually a simulator capability (at People API team's request)
// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
std::string mNameLookupURL;
// Accumulated agent IDs for next query against service
typedef std::set<LLUUID> ask_queue_t;
ask_queue_t mAskQueue;
// Agent IDs that have been requested, but with no reply.
// Maps agent ID to frame time request was made.
typedef std::map<LLUUID, F64> pending_queue_t;
pending_queue_t mPendingQueue;
// Callbacks to fire when we received a name.
// May have multiple callbacks for a single ID, which are
// represented as multiple slots bound to the signal.
// Avoid copying signals via pointers.
typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
signal_map_t mSignalMap;
// The cache at last, i.e. avatar names we know about.
typedef std::map<LLUUID, LLAvatarName> cache_t;
cache_t mCache;
// Time when unrefreshed cached names were checked last.
F64 mLastExpireCheck;
};
// Parse a cache-control header to get the max-age delta-seconds.
// Returns true if header has max-age param and it parses correctly.

View File

@ -4509,7 +4509,7 @@ void LLAppViewer::loadNameCache()
llifstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
if ( ! LLAvatarNameCache::importFile(name_cache_stream))
if ( ! LLAvatarNameCache::getInstance()->importFile(name_cache_stream))
{
LL_WARNS("AppInit") << "removing invalid '" << filename << "'" << LL_ENDL;
name_cache_stream.close();
@ -4536,7 +4536,7 @@ void LLAppViewer::saveNameCache()
llofstream name_cache_stream(filename.c_str());
if(name_cache_stream.is_open())
{
LLAvatarNameCache::exportFile(name_cache_stream);
LLAvatarNameCache::getInstance()->exportFile(name_cache_stream);
}
// real names cache
@ -5143,7 +5143,8 @@ void LLAppViewer::idleNameCache()
// granted to neighbor regions before the main agent gets there. Can't
// do it in the move-into-region code because cap not guaranteed to be
// granted yet, for example on teleport.
bool had_capability = LLAvatarNameCache::hasNameLookupURL();
LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
name_lookup_url = region->getCapability("GetDisplayNames");
@ -5160,12 +5161,12 @@ void LLAppViewer::idleNameCache()
{
name_lookup_url += '/';
}
LLAvatarNameCache::setNameLookupURL(name_lookup_url);
name_cache->setNameLookupURL(name_lookup_url);
}
else
{
// Display names not available on this region
LLAvatarNameCache::setNameLookupURL( std::string() );
name_cache->setNameLookupURL( std::string() );
}
// Error recovery - did we change state?
@ -5175,7 +5176,7 @@ void LLAppViewer::idleNameCache()
LLVOAvatar::invalidateNameTags();
}
LLAvatarNameCache::idle();
name_cache->idle();
}
//

View File

@ -154,7 +154,7 @@ LLAvatarList::LLAvatarList(const Params& p)
mLITUpdateTimer->start();
}
LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this));
LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this));
}

View File

@ -221,7 +221,7 @@ void LLFloaterConversationPreview::showHistory()
else
{
std::string legacy_name = gCacheName->buildLegacyName(from);
from_id = LLAvatarNameCache::findIdByName(legacy_name);
from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
LLChat chat;

View File

@ -237,7 +237,7 @@ BOOL LLFloaterIMContainer::postBuild()
collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false);
LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed())
@ -267,7 +267,7 @@ BOOL LLFloaterIMContainer::postBuild()
// We'll take care of view updates on idle
gIdleCallbacks.addFunction(idle, this);
// When display name option change, we need to reload all participant names
LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
LLAvatarNameCache::getInstance()->addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
mParticipantRefreshTimer.setTimerExpirySec(0);
mParticipantRefreshTimer.start();

View File

@ -228,7 +228,7 @@ void LLFloaterIMNearbyChat::loadHistory()
else
{
std::string legacy_name = gCacheName->buildLegacyName(from);
from_id = LLAvatarNameCache::findIdByName(legacy_name);
from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
LLChat chat;

View File

@ -278,13 +278,13 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
void handleNameTagOptionChanged(const LLSD& newvalue)
{
LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
LLAvatarNameCache::getInstance()->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
LLVOAvatar::invalidateNameTags();
}
void handleDisplayNamesOptionChanged(const LLSD& newvalue)
{
LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean());
LLAvatarNameCache::getInstance()->setUseDisplayNames(newvalue.asBoolean());
LLVOAvatar::invalidateNameTags();
}

View File

@ -695,7 +695,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
// The group notice packet does not have an AgentID. Obtain one from the name cache.
// If last name is "Resident" strip it out so the cache name lookup works.
std::string legacy_name = gCacheName->buildLegacyName(original_name);
agent_id = LLAvatarNameCache::findIdByName(legacy_name);
agent_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
if (agent_id.isNull())
{

View File

@ -806,7 +806,7 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
{
// convert it to a legacy name if we have a complete name
std::string legacy_name = gCacheName->buildLegacyName(from);
from_id = LLAvatarNameCache::findIdByName(legacy_name);
from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
}
std::string timestamp = msg[LL_IM_TIME];

View File

@ -177,7 +177,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
{
// Legacy support and fallback method
// if we can't retrieve sender id from group notice system message, try to lookup it from cache
sender_id = LLAvatarNameCache::findIdByName(sender_name);
sender_id = LLAvatarNameCache::getInstance()->findIdByName(sender_name);
}
logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],

View File

@ -2833,9 +2833,10 @@ void LLStartUp::initNameCache()
// Start cache in not-running state until we figure out if we have
// capabilities for display name lookup
LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
LLAvatarNameCache* cache_inst = LLAvatarNameCache::getInstance();
cache_inst->setUsePeopleAPI(gSavedSettings.getBOOL("UsePeopleAPI"));
cache_inst->setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
cache_inst->setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
}
@ -2850,8 +2851,6 @@ void LLStartUp::initExperiences()
void LLStartUp::cleanupNameCache()
{
SUBSYSTEM_CLEANUP(LLAvatarNameCache);
delete gCacheName;
gCacheName = NULL;
}

View File

@ -8653,7 +8653,6 @@ class LLWorldPostProcess : public view_listener_t
void handle_flush_name_caches()
{
SUBSYSTEM_CLEANUP(LLAvatarNameCache);
if (gCacheName) gCacheName->clear();
}