Debouncing of file updates in monitored dir

Now updates to ZIM files that failed to be added to the library upon
their appearance in a monitored dir are not handled immediately. Instead
they are debounced (deferred/delayed by 1 second) and processed only
after the file has been observed to be stable for some time (1 second as
of this commit).
This commit is contained in:
Veloman Yunkan 2024-08-25 15:16:50 +04:00 committed by Kelson
parent fdac248492
commit c3a4164541
2 changed files with 52 additions and 3 deletions

View File

@ -928,7 +928,9 @@ const char* monitoredDirZimFileHandlingMsgs[] = {
"it is being downloaded by us, ignoring...",
"the file was added to the library",
"the file could not be added to the library",
"it is an unchanged known bad zim file"
"it is an unchanged known bad zim file",
"deferring the check of an updated bad zim file",
"bad zim file was updated but a deferred request to check it is pending"
};
#endif
@ -943,12 +945,26 @@ bool ContentManager::handleZimFileInMonitoredDirLogged(QString dir, QString file
return status == MonitoredZimFileInfo::ADDED_TO_THE_LIBRARY;
}
bool ContentManager::MonitoredZimFileInfo::fileKeepsBeingModified() const
{
// A file is considered stable if it has stayed unchanged for at least
// this long.
const qint64 FILE_STABILITY_DURATION_MS = 1000;
const QDateTime now = QDateTime::currentDateTime();
return this->lastModified > now.addMSecs(-FILE_STABILITY_DURATION_MS);
}
void ContentManager::MonitoredZimFileInfo::updateStatus(const MonitoredZimFileInfo& prevInfo)
{
Q_ASSERT(prevInfo.status != ADDED_TO_THE_LIBRARY);
if ( this->lastModified == prevInfo.lastModified ) {
this->status = UNCHANGED_KNOWN_BAD_ZIM_FILE;
} else if ( prevInfo.status == PROCESS_LATER ) {
this->status = DEFERRED_PROCESSING_ALREADY_PENDING;
} else if ( this->fileKeepsBeingModified() ) {
this->status = PROCESS_LATER;
} else {
this->status = PROCESS_NOW;
}
@ -980,7 +996,9 @@ int ContentManager::handleZimFileInMonitoredDir(QString dir, QString fileName)
}
MonitoredZimFileInfo zfi = getMonitoredZimFileInfo(dir, fileName);
if ( zfi.status == MonitoredZimFileInfo::PROCESS_NOW ) {
if ( zfi.status == MonitoredZimFileInfo::PROCESS_LATER ) {
deferHandlingOfZimFileInMonitoredDir(dir, fileName);
} else if ( zfi.status == MonitoredZimFileInfo::PROCESS_NOW ) {
kiwix::Manager manager(mp_library->getKiwixLibrary());
const bool addedToLib = manager.addBookFromPath(bookPath.toStdString());
zfi.status = addedToLib
@ -1023,6 +1041,28 @@ void ContentManager::updateLibraryFromDir(QString dirPath)
}
}
void ContentManager::handleZimFileInMonitoredDirDeferred(QString dir, QString fileName)
{
QMutexLocker locker(&m_updateFromDirMutex);
DBGOUT("ContentManager::handleZimFileInMonitoredDirDeferred(" << dir << ", " << fileName << ")");
m_knownZimsInDir[dir][fileName].status = MonitoredZimFileInfo::PROCESS_NOW;
if ( handleZimFileInMonitoredDirLogged(dir, fileName) ) {
mp_library->save();
emit(booksChanged());
}
}
void ContentManager::deferHandlingOfZimFileInMonitoredDir(QString dir, QString fname)
{
const qint64 DEBOUNCING_DELAY_MILLISECONDS = 1000;
m_knownZimsInDir[dir][fname].status = MonitoredZimFileInfo::PROCESS_LATER;
QTimer::singleShot(DEBOUNCING_DELAY_MILLISECONDS, this, [=]() {
handleZimFileInMonitoredDirDeferred(dir, fname);
});
}
bool ContentManager::handleDisappearedBook(QString bookId)
{
if ( KiwixApp::instance()->getTabWidget()->getTabZimIds().contains(bookId) )

View File

@ -127,9 +127,16 @@ private: // types
// the file couldn't be added to the library earlier and hasn't
// changed since then
UNCHANGED_KNOWN_BAD_ZIM_FILE
UNCHANGED_KNOWN_BAD_ZIM_FILE,
// try to add this file to the library at a later time
PROCESS_LATER,
// this file is known to be enqueued for later processing
DEFERRED_PROCESSING_ALREADY_PENDING
};
bool fileKeepsBeingModified() const;
void updateStatus(const MonitoredZimFileInfo& prevInfo);
ZimFileStatus status = PROCESS_NOW;
@ -154,6 +161,8 @@ private: // functions
bool handleZimFileInMonitoredDirLogged(QString dirPath, QString fileName);
int handleZimFileInMonitoredDir(QString dirPath, QString fileName);
MonitoredZimFileInfo getMonitoredZimFileInfo(QString dir, QString fileName) const;
void deferHandlingOfZimFileInMonitoredDir(QString dir, QString fileName);
void handleZimFileInMonitoredDirDeferred(QString dirPath, QString fileName);
bool handleDisappearedBook(QString bookId);
// Get the book with the specified id from