diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-07-11 00:47:12 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2025-07-11 20:31:32 +0300 | 
| commit | c488919ef296cd763346b48195a17d099dd19f8c (patch) | |
| tree | c126998cd3c204afbd443848f40d30a64352f8da | |
| parent | 2e931a55adef97812f9673b8b03691bfa134403b (diff) | |
#4267 Offline messages not being requested
According to logs onFileMuteList doesn't get triggered.
I was able to repro, server just doesn't respond when file doesn't exist
server side.
As a workaround added timeout and state tracking into LLMuteList.
| -rw-r--r-- | indra/newview/llimprocessing.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llmutelist.cpp | 50 | ||||
| -rw-r--r-- | indra/newview/llmutelist.h | 14 | 
3 files changed, 58 insertions, 10 deletions
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 4c02511268..7cd0171a37 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1520,10 +1520,10 @@ void LLIMProcessing::requestOfflineMessages()      if (!requested          && gMessageSystem          && !gDisconnected -        && LLMuteList::getInstance()->isLoaded()          && isAgentAvatarValid()          && gAgent.getRegion() -        && gAgent.getRegion()->capabilitiesReceived()) +        && gAgent.getRegion()->capabilitiesReceived() +        && (LLMuteList::getInstance()->isLoaded() || LLMuteList::getInstance()->getLoadFailed()))      {          std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs"); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 2d51acc063..b044f6ad29 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -154,7 +154,8 @@ std::string LLMute::getDisplayType() const  // LLMuteList()  //-----------------------------------------------------------------------------  LLMuteList::LLMuteList() : -    mIsLoaded(false) +    mLoadState(ML_INITIAL), +    mRequestStartTime(0.f)  {      gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); @@ -209,6 +210,23 @@ bool LLMuteList::isLinden(const std::string& name)      return last_name == "linden";  } +bool LLMuteList::getLoadFailed() const +{ +    if (mLoadState == ML_FAILED) +    { +        return true; +    } +    if (mLoadState == ML_REQUESTED) +    { +        constexpr F64 WAIT_SECONDS = 30; +        if (mRequestStartTime + WAIT_SECONDS > LLTimer::getTotalSeconds()) +        { +            return true; +        } +    } +    return false; +} +  static LLVOAvatar* find_avatar(const LLUUID& id)  {      LLViewerObject *obj = gObjectList.findObject(id); @@ -371,11 +389,14 @@ void LLMuteList::updateAdd(const LLMute& mute)      msg->addU32("MuteFlags", mute.mFlags);      gAgent.sendReliableMessage(); -    if (!mIsLoaded) +    if (!isLoaded())      {          LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;      } -    mIsLoaded = true; // why is this here? -MG +    // Based of logs and testing, if file doesn't exist server side, +    // viewer will not receive any callback and won't know to set +    // ML_LOADED. As a workaround, set it regardless of current state. +    mLoadState = ML_LOADED;  } @@ -564,6 +585,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)      if(!filename.size())      {          LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; +        mLoadState = ML_FAILED;          return false;      } @@ -571,6 +593,7 @@ bool LLMuteList::loadFromFile(const std::string& filename)      if (!fp)      {          LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL; +        mLoadState = ML_FAILED;          return false;      } @@ -730,13 +753,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)      if (gDisconnected)      {          LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; +        mLoadState = ML_FAILED;          return;      }      if (!gAgent.getRegion())      {          LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL; +        mLoadState = ML_FAILED;          return;      } +    mLoadState = ML_REQUESTED; +    mRequestStartTime = LLTimer::getElapsedSeconds();      // Double amount of retries due to this request happening during busy stage      // Ideally this should be turned into a capability      gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); @@ -749,7 +776,7 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)  void LLMuteList::cache(const LLUUID& agent_id)  {      // Write to disk even if empty. -    if(mIsLoaded) +    if(isLoaded())      {          std::string agent_id_string;          std::string filename; @@ -777,6 +804,13 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**)      msg->getStringFast(_PREHASH_MuteData, _PREHASH_Filename, unclean_filename);      std::string filename = LLDir::getScrubbedFileName(unclean_filename); +    LLMuteList* mute_list = getInstance(); +    mute_list->mLoadState = ML_REQUESTED; +    mute_list->mRequestStartTime = LLTimer::getElapsedSeconds(); + +    // Todo: Based of logs and testing, there is no callback +    // from server if file doesn't exist server side. +    // Once server side gets fixed make sure it gets handled right.      std::string *local_filename_and_path = new std::string(gDirUtilp->getExpandedFilename( LL_PATH_CACHE, filename ));      gXferManager->requestFile(*local_filename_and_path,                                filename, @@ -809,12 +843,16 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_          LLMuteList::getInstance()->loadFromFile(*local_filename_and_path);          LLFile::remove(*local_filename_and_path);      } +    else +    { +        LLMuteList::getInstance()->mLoadState = ML_FAILED; +    }      delete local_filename_and_path;  }  void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)  { -    if (mIsLoaded) +    if (isLoaded())      {          LLMute mute(id, username, LLMute::AGENT);          mute_set_t::iterator mute_it = mMutes.find(mute); @@ -866,7 +904,7 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer)  void LLMuteList::setLoaded()  { -    mIsLoaded = true; +    mLoadState = ML_LOADED;      notifyObservers();  } diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 13d579c61f..b65fd61fcc 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -74,6 +74,14 @@ class LLMuteList : public LLSingleton<LLMuteList>      LLSINGLETON(LLMuteList);      ~LLMuteList();      /*virtual*/ void cleanupSingleton() override; + +    enum EMuteListState +    { +        ML_INITIAL, +        ML_REQUESTED, +        ML_LOADED, +        ML_FAILED, +    };  public:      // reasons for auto-unmuting a resident      enum EAutoReason @@ -107,7 +115,8 @@ public:      static bool isLinden(const std::string& name); -    bool isLoaded() const { return mIsLoaded; } +    bool isLoaded() const { return mLoadState == ML_LOADED; } +    bool getLoadFailed() const;      std::vector<LLMute> getMutes() const; @@ -167,7 +176,8 @@ private:      typedef std::set<LLMuteListObserver*> observer_set_t;      observer_set_t mObservers; -    bool mIsLoaded; +    EMuteListState mLoadState; +    F64 mRequestStartTime;      friend class LLDispatchEmptyMuteList;  };  | 
