Skip to content

Commit

Permalink
Debouncing of file updates in monitored dir
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
veloman-yunkan authored and kelson42 committed Sep 7, 2024
1 parent fdac248 commit c3a4164
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
44 changes: 42 additions & 2 deletions src/contentmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) )
Expand Down
11 changes: 10 additions & 1 deletion src/contentmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,16 @@ public slots:

// 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;
Expand All @@ -154,6 +161,8 @@ public slots:
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
Expand Down

0 comments on commit c3a4164

Please sign in to comment.