-
Notifications
You must be signed in to change notification settings - Fork 113
Mute list fallback to cache if timed out #5269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 4 commits
6f224ca
92b92db
abca0d9
34ca50b
3fd1d6a
d8f8623
9dfcf21
05ab587
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -92,7 +92,9 @@ class LLDispatchEmptyMuteList : public LLDispatchHandler | |||||||
| const LLUUID& invoice, | ||||||||
| const sparam_t& strings) | ||||||||
| { | ||||||||
| LLMuteList::getInstance()->setLoaded(); | ||||||||
| LLMuteList* mute_list = LLMuteList::getInstance(); | ||||||||
| mute_list->clearCachedMutes(); | ||||||||
| mute_list->setLoaded(LLMuteList::MLS_SERVER_EMPTY); | ||||||||
| return true; | ||||||||
| } | ||||||||
| }; | ||||||||
|
|
@@ -155,7 +157,9 @@ std::string LLMute::getDisplayType() const | |||||||
| //----------------------------------------------------------------------------- | ||||||||
| LLMuteList::LLMuteList() : | ||||||||
| mLoadState(ML_INITIAL), | ||||||||
| mRequestStartTime(0.f) | ||||||||
| mLoadSource(MLS_NONE), | ||||||||
| mRequestStartTime(0.f), | ||||||||
| mTriedCacheFallback(false) | ||||||||
| { | ||||||||
| gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); | ||||||||
|
|
||||||||
|
|
@@ -210,9 +214,9 @@ bool LLMuteList::isLinden(const std::string& name) | |||||||
| return last_name == "linden"; | ||||||||
| } | ||||||||
|
|
||||||||
| bool LLMuteList::getLoadFailed() const | ||||||||
| bool LLMuteList::updateLoadState() | ||||||||
| { | ||||||||
| if (mLoadState == ML_FAILED) | ||||||||
| if (isLoaded() || isFailed()) | ||||||||
| { | ||||||||
| return true; | ||||||||
| } | ||||||||
|
|
@@ -221,9 +225,81 @@ bool LLMuteList::getLoadFailed() const | |||||||
| constexpr F64 WAIT_SECONDS = 30; | ||||||||
| if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds()) | ||||||||
| { | ||||||||
| return true; | ||||||||
| LL_WARNS() << "Mute list request timed out; trying cache fallback once" << LL_ENDL; | ||||||||
| tryLoadCacheFallback(gAgent.getID(), "request timeout"); | ||||||||
| return isLoaded() || isFailed(); | ||||||||
| } | ||||||||
| } | ||||||||
| return false; | ||||||||
|
Comment on lines
231
to
+247
|
||||||||
| } | ||||||||
|
|
||||||||
| void LLMuteList::clearCachedMutes() | ||||||||
| { | ||||||||
| mMutes.clear(); | ||||||||
| mLegacyMutes.clear(); | ||||||||
| } | ||||||||
|
|
||||||||
| const char* LLMuteList::sourceToString(EMuteListSource source) | ||||||||
| { | ||||||||
| switch (source) | ||||||||
| { | ||||||||
| case MLS_NONE: | ||||||||
| return "none"; | ||||||||
| case MLS_SERVER: | ||||||||
| return "server"; | ||||||||
| case MLS_SERVER_EMPTY: | ||||||||
| return "server-empty"; | ||||||||
| case MLS_SERVER_CACHE: | ||||||||
| return "server-cached"; | ||||||||
| case MLS_FALLBACK_CACHE: | ||||||||
| return "fallback-cache"; | ||||||||
| default: | ||||||||
| return "unknown"; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| std::string LLMuteList::getCacheFilename(const LLUUID& agent_id) const | ||||||||
| { | ||||||||
| std::string agent_id_string; | ||||||||
| agent_id.toString(agent_id_string); | ||||||||
| return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_string) + ".cached_mute"; | ||||||||
| } | ||||||||
|
|
||||||||
| void LLMuteList::setFailed(const std::string& reason) | ||||||||
| { | ||||||||
| mLoadState = ML_FAILED; | ||||||||
| if (mLoadSource == MLS_NONE) | ||||||||
| { | ||||||||
| LL_WARNS() << "Mute list unavailable: " << reason << LL_ENDL; | ||||||||
| } | ||||||||
| else | ||||||||
| { | ||||||||
| LL_WARNS() << "Mute list unavailable: " << reason << " (last source=" << sourceToString(mLoadSource) << ")" << LL_ENDL; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| bool LLMuteList::tryLoadCacheFallback(const LLUUID& agent_id, const std::string& reason) | ||||||||
| { | ||||||||
| if (mTriedCacheFallback) | ||||||||
| { | ||||||||
| if (!isLoaded()) | ||||||||
| { | ||||||||
| setFailed("cache fallback already attempted before " + reason); | ||||||||
| } | ||||||||
| return isLoaded(); | ||||||||
| } | ||||||||
|
|
||||||||
| mTriedCacheFallback = true; | ||||||||
| const std::string filename = getCacheFilename(agent_id); | ||||||||
| LL_INFOS() << "Trying mute list cache fallback due to " << reason << ": " << filename << LL_ENDL; | ||||||||
|
|
||||||||
| if (loadFromFile(filename, MLS_FALLBACK_CACHE)) | ||||||||
| { | ||||||||
| LL_WARNS() << "Loaded mute list from cache fallback due to " << reason << LL_ENDL; | ||||||||
| return true; | ||||||||
| } | ||||||||
akleshchev marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
|
||||||||
| setFailed("cache fallback failed after " + reason); | ||||||||
| return false; | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -580,25 +656,28 @@ std::vector<LLMute> LLMuteList::getMutes() const | |||||||
| //----------------------------------------------------------------------------- | ||||||||
| // loadFromFile() | ||||||||
| //----------------------------------------------------------------------------- | ||||||||
| bool LLMuteList::loadFromFile(const std::string& filename) | ||||||||
| bool LLMuteList::loadFromFile(const std::string& filename, EMuteListSource source) | ||||||||
| { | ||||||||
| LL_PROFILE_ZONE_SCOPED; | ||||||||
|
|
||||||||
| if(!filename.size()) | ||||||||
| { | ||||||||
| LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; | ||||||||
| mLoadState = ML_FAILED; | ||||||||
| setFailed("empty filename"); | ||||||||
| return false; | ||||||||
| } | ||||||||
|
|
||||||||
| LLFILE* fp = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ | ||||||||
| if (!fp) | ||||||||
| { | ||||||||
| LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL; | ||||||||
| mLoadState = ML_FAILED; | ||||||||
| setFailed("cannot open " + filename); | ||||||||
| return false; | ||||||||
| } | ||||||||
|
|
||||||||
| // Replace previous server-backed state so fallback can be superseded by authoritative data. | ||||||||
| clearCachedMutes(); | ||||||||
|
|
||||||||
| // *NOTE: Changing the size of these buffers will require changes | ||||||||
| // in the scanf below. | ||||||||
| char id_buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||||||||
|
|
@@ -627,7 +706,7 @@ bool LLMuteList::loadFromFile(const std::string& filename) | |||||||
| } | ||||||||
| } | ||||||||
| fclose(fp); | ||||||||
| setLoaded(); | ||||||||
| setLoaded(source); | ||||||||
|
|
||||||||
| // server does not maintain up-to date account names (not display names!) | ||||||||
| // in this list, so it falls to viewer. | ||||||||
|
|
@@ -737,12 +816,11 @@ bool LLMuteList::isMuted(const std::string& username, U32 flags) const | |||||||
| //----------------------------------------------------------------------------- | ||||||||
| void LLMuteList::requestFromServer(const LLUUID& agent_id) | ||||||||
| { | ||||||||
| std::string agent_id_string; | ||||||||
| std::string filename; | ||||||||
| agent_id.toString(agent_id_string); | ||||||||
| filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute"; | ||||||||
| const std::string filename = getCacheFilename(agent_id); | ||||||||
| LLCRC crc; | ||||||||
| crc.update(filename); | ||||||||
| mTriedCacheFallback = false; | ||||||||
| mLoadSource = MLS_NONE; | ||||||||
|
|
||||||||
| LLMessageSystem* msg = gMessageSystem; | ||||||||
| msg->newMessageFast(_PREHASH_MuteListRequest); | ||||||||
|
|
@@ -755,17 +833,19 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id) | |||||||
| if (gDisconnected) | ||||||||
| { | ||||||||
| LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; | ||||||||
| mLoadState = ML_FAILED; | ||||||||
| // Guard against potentially writing back to disk since we're not recovering our connection | ||||||||
| mLoadState = ML_LOADED; | ||||||||
| mLoadSource = MLS_FALLBACK_CACHE; | ||||||||
|
Comment on lines
+858
to
+859
|
||||||||
| mLoadState = ML_LOADED; | |
| mLoadSource = MLS_FALLBACK_CACHE; | |
| tryLoadCacheFallback(agent_id, "disconnected"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By setting the load state as loaded and source as cache, we're putting the state of the list in one that will not change again because it is loaded, and that won't be written to disk from cache(). I believe that calling tryLoadCacheFallback() in this code path unnecessary since we will no longer be handling messages from a server so the block list is no longer important to have in a reliable state.
Yes this is don't and say we did situation, but it's a safe lie in this case.
akleshchev marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a warns if we are setting ML_LOADED when it was already in the same state. It would be good for diagnosis to see potential 'overwrite' in logs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comment about the purpose of the 'clear'. That we received list from server, might have something from cache, but server takes priority?