Skip to content

Commit 6f224ca

Browse files
committed
Allow mute list to fallback to cached copy when simulator response somehow isn't received
Signed-off-by: Darl <me@darl.cat>
1 parent b4f1072 commit 6f224ca

2 files changed

Lines changed: 117 additions & 34 deletions

File tree

indra/newview/llmutelist.cpp

Lines changed: 99 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class LLDispatchEmptyMuteList : public LLDispatchHandler
9292
const LLUUID& invoice,
9393
const sparam_t& strings)
9494
{
95-
LLMuteList::getInstance()->setLoaded();
95+
LLMuteList::getInstance()->setLoaded(LLMuteList::MLS_SERVER_EMPTY);
9696
return true;
9797
}
9898
};
@@ -155,7 +155,9 @@ std::string LLMute::getDisplayType() const
155155
//-----------------------------------------------------------------------------
156156
LLMuteList::LLMuteList() :
157157
mLoadState(ML_INITIAL),
158-
mRequestStartTime(0.f)
158+
mLoadSource(MLS_NONE),
159+
mRequestStartTime(0.f),
160+
mTriedCacheFallback(false)
159161
{
160162
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
161163

@@ -210,7 +212,7 @@ bool LLMuteList::isLinden(const std::string& name)
210212
return last_name == "linden";
211213
}
212214

213-
bool LLMuteList::getLoadFailed() const
215+
bool LLMuteList::getLoadFailed()
214216
{
215217
if (mLoadState == ML_FAILED)
216218
{
@@ -221,12 +223,78 @@ bool LLMuteList::getLoadFailed() const
221223
constexpr F64 WAIT_SECONDS = 30;
222224
if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds())
223225
{
224-
return true;
226+
LL_WARNS() << "Mute list request timed out; trying cache fallback once" << LL_ENDL;
227+
tryLoadCacheFallback(gAgent.getID(), "request timeout");
228+
return mLoadState == ML_FAILED;
225229
}
226230
}
227231
return false;
228232
}
229233

234+
const char* LLMuteList::sourceToString(EMuteListSource source)
235+
{
236+
switch (source)
237+
{
238+
case MLS_NONE:
239+
return "none";
240+
case MLS_SERVER:
241+
return "server";
242+
case MLS_SERVER_EMPTY:
243+
return "server-empty";
244+
case MLS_SERVER_CACHE:
245+
return "server-cached";
246+
case MLS_FALLBACK_CACHE:
247+
return "fallback-cache";
248+
default:
249+
return "unknown";
250+
}
251+
}
252+
253+
std::string LLMuteList::getCacheFilename(const LLUUID& agent_id) const
254+
{
255+
std::string agent_id_string;
256+
agent_id.toString(agent_id_string);
257+
return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_string) + ".cached_mute";
258+
}
259+
260+
void LLMuteList::setFailed(const std::string& reason)
261+
{
262+
mLoadState = ML_FAILED;
263+
if (mLoadSource == MLS_NONE)
264+
{
265+
LL_WARNS() << "Mute list unavailable: " << reason << LL_ENDL;
266+
}
267+
else
268+
{
269+
LL_WARNS() << "Mute list unavailable: " << reason << " (last source=" << sourceToString(mLoadSource) << ")" << LL_ENDL;
270+
}
271+
}
272+
273+
bool LLMuteList::tryLoadCacheFallback(const LLUUID& agent_id, const std::string& reason)
274+
{
275+
if (mTriedCacheFallback)
276+
{
277+
if (!isLoaded())
278+
{
279+
setFailed("cache fallback already attempted before " + reason);
280+
}
281+
return isLoaded();
282+
}
283+
284+
mTriedCacheFallback = true;
285+
const std::string filename = getCacheFilename(agent_id);
286+
LL_INFOS() << "Trying mute list cache fallback due to " << reason << ": " << filename << LL_ENDL;
287+
288+
if (loadFromFile(filename, MLS_FALLBACK_CACHE))
289+
{
290+
LL_WARNS() << "Loaded mute list from cache fallback due to " << reason << LL_ENDL;
291+
return true;
292+
}
293+
294+
setFailed("cache fallback failed after " + reason);
295+
return false;
296+
}
297+
230298
static LLVOAvatar* find_avatar(const LLUUID& id)
231299
{
232300
LLViewerObject *obj = gObjectList.findObject(id);
@@ -580,25 +648,29 @@ std::vector<LLMute> LLMuteList::getMutes() const
580648
//-----------------------------------------------------------------------------
581649
// loadFromFile()
582650
//-----------------------------------------------------------------------------
583-
bool LLMuteList::loadFromFile(const std::string& filename)
651+
bool LLMuteList::loadFromFile(const std::string& filename, EMuteListSource source)
584652
{
585653
LL_PROFILE_ZONE_SCOPED;
586654

587655
if(!filename.size())
588656
{
589657
LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL;
590-
mLoadState = ML_FAILED;
658+
setFailed("empty filename");
591659
return false;
592660
}
593661

594662
LLFILE* fp = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
595663
if (!fp)
596664
{
597665
LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL;
598-
mLoadState = ML_FAILED;
666+
setFailed("cannot open " + filename);
599667
return false;
600668
}
601669

670+
// Replace previous server-backed state so fallback can be superseded by authoritative data.
671+
mMutes.clear();
672+
mLegacyMutes.clear();
673+
602674
// *NOTE: Changing the size of these buffers will require changes
603675
// in the scanf below.
604676
char id_buffer[MAX_STRING]; /*Flawfinder: ignore*/
@@ -627,7 +699,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)
627699
}
628700
}
629701
fclose(fp);
630-
setLoaded();
702+
setLoaded(source);
631703

632704
// server does not maintain up-to date account names (not display names!)
633705
// in this list, so it falls to viewer.
@@ -737,12 +809,11 @@ bool LLMuteList::isMuted(const std::string& username, U32 flags) const
737809
//-----------------------------------------------------------------------------
738810
void LLMuteList::requestFromServer(const LLUUID& agent_id)
739811
{
740-
std::string agent_id_string;
741-
std::string filename;
742-
agent_id.toString(agent_id_string);
743-
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
812+
const std::string filename = getCacheFilename(agent_id);
744813
LLCRC crc;
745814
crc.update(filename);
815+
mTriedCacheFallback = false;
816+
mLoadSource = MLS_NONE;
746817

747818
LLMessageSystem* msg = gMessageSystem;
748819
msg->newMessageFast(_PREHASH_MuteListRequest);
@@ -755,17 +826,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
755826
if (gDisconnected)
756827
{
757828
LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
758-
mLoadState = ML_FAILED;
829+
tryLoadCacheFallback(agent_id, "disconnected before request");
759830
return;
760831
}
761832
if (!gAgent.getRegion())
762833
{
763834
LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
764-
mLoadState = ML_FAILED;
835+
tryLoadCacheFallback(agent_id, "no region for request");
765836
return;
766837
}
767838
mLoadState = ML_REQUESTED;
768-
mRequestStartTime = LLTimer::getElapsedSeconds();
839+
mRequestStartTime = LLTimer::getTotalSeconds();
769840
// Double amount of retries due to this request happening during busy stage
770841
// Ideally this should be turned into a capability
771842
gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
@@ -777,15 +848,16 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
777848

778849
void LLMuteList::cache(const LLUUID& agent_id)
779850
{
780-
// Write to disk even if empty.
781-
if(isLoaded())
851+
// Write to disk even if empty, but never from degraded fallback state.
852+
if (isLoaded() && mLoadSource != MLS_FALLBACK_CACHE)
782853
{
783-
std::string agent_id_string;
784-
std::string filename;
785-
agent_id.toString(agent_id_string);
786-
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
854+
const std::string filename = getCacheFilename(agent_id);
787855
saveToFile(filename);
788856
}
857+
else if (isLoaded())
858+
{
859+
LL_WARNS() << "Skipping mute list cache write from fallback-only state" << LL_ENDL;
860+
}
789861
}
790862

791863
//-----------------------------------------------------------------------------
@@ -812,7 +884,7 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)
812884

813885
LLMuteList* mute_list = getInstance();
814886
mute_list->mLoadState = ML_REQUESTED;
815-
mute_list->mRequestStartTime = LLTimer::getElapsedSeconds();
887+
mute_list->mRequestStartTime = LLTimer::getTotalSeconds();
816888

817889
// Todo: Based of logs and testing, there is no callback
818890
// from server if file doesn't exist server side.
@@ -831,12 +903,7 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)
831903
void LLMuteList::processUseCachedMuteList(LLMessageSystem* msg, void**)
832904
{
833905
LL_INFOS() << "LLMuteList::processUseCachedMuteList()" << LL_ENDL;
834-
835-
std::string agent_id_string;
836-
gAgent.getID().toString(agent_id_string);
837-
std::string filename;
838-
filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute";
839-
LLMuteList::getInstance()->loadFromFile(filename);
906+
LLMuteList::getInstance()->loadFromFile(LLMuteList::getInstance()->getCacheFilename(gAgent.getID()), MLS_SERVER_CACHE);
840907
}
841908

842909
void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_status)
@@ -845,13 +912,13 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
845912
if(local_filename_and_path && !local_filename_and_path->empty() && (error_code == 0))
846913
{
847914
LL_INFOS() << "Received mute list from server" << LL_ENDL;
848-
LLMuteList::getInstance()->loadFromFile(*local_filename_and_path);
915+
LLMuteList::getInstance()->loadFromFile(*local_filename_and_path, MLS_SERVER);
849916
LLFile::remove(*local_filename_and_path);
850917
}
851918
else
852919
{
853920
LL_INFOS() << "LLMuteList xfer failed with code " << error_code << LL_ENDL;
854-
LLMuteList::getInstance()->mLoadState = ML_FAILED;
921+
LLMuteList::getInstance()->tryLoadCacheFallback(gAgent.getID(), "xfer failure");
855922
}
856923
delete local_filename_and_path;
857924
}
@@ -908,9 +975,10 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer)
908975
mObservers.erase(observer);
909976
}
910977

911-
void LLMuteList::setLoaded()
978+
void LLMuteList::setLoaded(EMuteListSource source)
912979
{
913980
mLoadState = ML_LOADED;
981+
mLoadSource = source;
914982
notifyObservers();
915983
}
916984

indra/newview/llmutelist.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ class LLMuteList : public LLSingleton<LLMuteList>
8282
ML_LOADED,
8383
ML_FAILED,
8484
};
85+
86+
enum EMuteListSource
87+
{
88+
MLS_NONE,
89+
MLS_SERVER,
90+
MLS_SERVER_EMPTY,
91+
MLS_SERVER_CACHE,
92+
MLS_FALLBACK_CACHE,
93+
};
8594
public:
8695
// reasons for auto-unmuting a resident
8796
enum EAutoReason
@@ -116,7 +125,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
116125
static bool isLinden(const std::string& name);
117126

118127
bool isLoaded() const { return mLoadState == ML_LOADED; }
119-
bool getLoadFailed() const;
128+
bool getLoadFailed();
120129

121130
std::vector<LLMute> getMutes() const;
122131

@@ -127,10 +136,14 @@ class LLMuteList : public LLSingleton<LLMuteList>
127136
void cache(const LLUUID& agent_id);
128137

129138
private:
130-
bool loadFromFile(const std::string& filename);
139+
bool loadFromFile(const std::string& filename, EMuteListSource source);
131140
bool saveToFile(const std::string& filename);
141+
bool tryLoadCacheFallback(const LLUUID& agent_id, const std::string& reason);
142+
void setFailed(const std::string& reason);
143+
static const char* sourceToString(EMuteListSource source);
144+
std::string getCacheFilename(const LLUUID& agent_id) const;
132145

133-
void setLoaded();
146+
void setLoaded(EMuteListSource source);
134147
void notifyObservers();
135148
void notifyObserversDetailed(const LLMute &mute);
136149

@@ -177,7 +190,9 @@ class LLMuteList : public LLSingleton<LLMuteList>
177190
observer_set_t mObservers;
178191

179192
EMuteListState mLoadState;
193+
EMuteListSource mLoadSource;
180194
F64 mRequestStartTime;
195+
bool mTriedCacheFallback;
181196

182197
friend class LLDispatchEmptyMuteList;
183198
};

0 commit comments

Comments
 (0)