Fix issue with persistent notifications. open_notifications.xml was accumulating inaccessible notifications. Added MaxPersistentNotifications to cap notifications. Notifications new stored per account per grid. Startup should be faster too.

This commit is contained in:
Shyotl
2020-05-09 04:50:01 -05:00
parent 3c3d8c2400
commit 61f90c665a
5 changed files with 99 additions and 42 deletions

View File

@@ -74,8 +74,9 @@ private:
bool historyHandler(const LLSD& payload)
{
// we ignore "load" messages, but rewrite the persistence file on any other
// onDelete handes "delete" message, so skip that too.
std::string sigtype = payload["sigtype"];
if (sigtype != "load")
if (sigtype != "load" && sigtype != "delete")
{
savePersistentNotifications();
}
@@ -85,11 +86,15 @@ private:
// The history channel gets all notifications except those that have been cancelled
static bool historyFilter(LLNotificationPtr pNotification)
{
return !pNotification->isCancelled();
return pNotification->isPersistent() && !pNotification->isCancelled() && !pNotification->isRespondedTo() && !pNotification->isExpired();
}
void savePersistentNotifications()
{
if (mLoading)
{
return;
}
LL_INFOS() << "Saving open notifications to " << mFileName << LL_ENDL;
llofstream notify_file(mFileName.c_str());
@@ -104,6 +109,9 @@ private:
LLSD& data = output["data"];
AILOCK_mItems;
static LLCachedControl<S32> maxPersistentNotificaitons("MaxPersistentNotifications");
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
if (!LLNotificationTemplates::instance().templateExists((*it)->getName())) continue;
@@ -111,7 +119,15 @@ private:
// only store notifications flagged as persisting
LLNotificationTemplatePtr templatep = LLNotificationTemplates::instance().getTemplate((*it)->getName());
if (!templatep->mPersist) continue;
if ((*it)->isCancelled() || (*it)->isExpired() || (*it)->isRespondedTo()) continue;
if (data.size() >= maxPersistentNotificaitons)
{
LL_WARNS() << "Too many persistent notifications."
<< " Saved " << maxPersistentNotificaitons << " of " << mItems.size()
<< " persistent notifications." << LL_ENDL;
break;
}
data.append((*it)->asLLSD());
}
@@ -121,53 +137,75 @@ private:
void loadPersistentNotifications()
{
if (mLoading)
{
return;
}
mLoading = true;
LL_INFOS() << "Loading open notifications from " << mFileName << LL_ENDL;
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
while (true)
{
LL_WARNS() << "Failed to open " << mFileName << LL_ENDL;
return;
}
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
LL_WARNS() << "Failed to open " << mFileName << LL_ENDL;
break;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
LL_WARNS() << "Failed to parse open notifications" << LL_ENDL;
return;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
LL_WARNS() << "Failed to parse open notifications" << LL_ENDL;
break;
}
if (input.isUndefined()) return;
std::string version = input["version"];
if (version != NOTIFICATION_PERSIST_VERSION)
{
LL_WARNS() << "Bad open notifications version: " << version << LL_ENDL;
return;
}
LLSD& data = input["data"];
if (data.isUndefined()) return;
if (input.isUndefined()) return;
std::string version = input["version"];
if (version != NOTIFICATION_PERSIST_VERSION)
{
LL_WARNS() << "Bad open notifications version: " << version << LL_ENDL;
break;
}
LLSD& data = input["data"];
if (data.isUndefined()) break;
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
S32 processed_notifications = 0;
static LLCachedControl<S32> maxPersistentNotificaitons("MaxPersistentNotifications");
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
if (processed_notifications++ >= maxPersistentNotificaitons)
{
LL_WARNS() << "Too many persistent notifications."
<< " Processed " << maxPersistentNotificaitons << " of " << data.size() << " persistent notifications." << LL_ENDL;
break;
}
instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
}
break;
}
mLoading = false;
savePersistentNotifications();
}
//virtual
void onDelete(LLNotificationPtr pNotification)
{
// we want to keep deleted notifications in our log
AILOCK_mItems;
mItems.insert(pNotification);
return;
{
AILOCK_mItems;
mItems.erase(pNotification); // Delete immediately.
}
savePersistentNotifications();
}
private:
bool mLoading = false;
std::string mFileName;
};
@@ -277,6 +315,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP
}
LLNotificationForm::LLNotificationForm(const LLSD& sd)
: mIgnore(IGNORE_NO)
{
if (sd.isArray())
{
@@ -904,9 +943,9 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
// if we have it in our list, pass on the delete, then delete it, else do nothing
if (wasFound)
{
onDelete(pNotification);
abortProcessing = mChanged(payload);
mItems.erase(pNotification);
onDelete(pNotification);
}
}
return abortProcessing;
@@ -1146,13 +1185,6 @@ void LLNotifications::createDefaultChannels()
LLNotificationChannel::buildChannel("Visible", "Ignore",
&LLNotificationFilters::includeEverything);
// create special history channel
//std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
// use ^^^ when done debugging notifications serialization
std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
// this isn't a leak, don't worry about the empty "new"
new LLNotificationHistoryChannel(notifications_log_file);
// connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->
connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
@@ -1164,6 +1196,14 @@ void LLNotifications::createDefaultChannels()
connectFailedFilter(&handleIgnoredNotification);
}
void LLNotifications::onLoginCompleted()
{
// create special history channel
std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "singu_open_notifications_" + gHippoGridManager->getCurrentGrid()->getGridName() + ".xml");
// this isn't a leak, don't worry about the empty "new"
new LLNotificationHistoryChannel(notifications_log_file );
}
static std::string sStringSkipNextTime("Skip this dialog next time");
static std::string sStringAlwaysChoose("Always choose this option");

View File

@@ -796,6 +796,7 @@ public:
// OK to call more than once because it will reload
bool loadNotifications();
void createDefaultChannels();
void onLoginCompleted();
// we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
LLNotificationPtr add(const std::string& name,

View File

@@ -10576,6 +10576,17 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<real>1.6</real>
</map>
<key>MaxPersistentNotifications</key>
<map>
<key>Comment</key>
<string>Maximum amount of persistent notifications</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<real>250</real>
</map>
<key>MaxSelectDistance</key>
<map>
<key>Comment</key>

View File

@@ -5084,6 +5084,10 @@ void LLAppViewer::handleLoginComplete()
}
mOnLoginCompleted();
// Singu Note: This would usually be registered via mOnLoginCompleted, but that would require code in newview regardless so.. just call directly here.
LLNotifications::instance().onLoginCompleted();
// Singu Note: Due to MAINT-4001, we must do this here, it lives in LLSidepanelInventory::updateInbox upstream.
// Consolidate Received items
// We shouldn't have to do that but with a client/server system relying on a "well known folder" convention,

View File

@@ -553,6 +553,7 @@ BOOL LLNotifyBox::tick()
{
if (mIsTip)
{
LLNotifications::instance().cancel(mNotification);
close();
}
return FALSE;