Skip to content

FileMonitoringManager does not detect modified files when they're overwritten by new added files #81

@fxdeniz

Description

@fxdeniz

Assume a case where we have a file called file.xlsx and it's updated by user. In this case, excel will create a temporary file such as 0A9C1FDA.tmp and this file be the new file.xlsx. (.tmp file be written over .xlsx file by the excel)

This was a known and handled case. But, I think I missed something in the logic. The case I described sometimes detected correctly sometimes not detected.

This bug happens in FileMonitoringManager::slotOnMoveEventDetected() here is the logic:

QFileInfo info(_dir + fileName);
if (info.isFile())
{
    bool isOldFileExist = this->mddb.isFileExistInDir(oldFileName, dir);
    bool isNewFileExist = this->mddb.isFileExistInDir(fileName, dir);

    if(isOldFileExist && !isNewFileExist)
    {
            auto currentState = this->mddb.stateOfFileInDir(fileName, dir);

          // Do not count renames (moves) if files is new added.
          if(currentState != MonitoredDirDb::MonitoredItemState::NewAdded)     <------- Check 1
          {
              // Here categorize files as Moved or MovedAndModified        
          }

          this->mddb.updateEventTimestampOfFileInDir(fileName, dir, QDateTime::currentDateTime());
    }
    else if(isOldFileExist && isNewFileExist) // Ghost file cleanup
    {
        this->mddb.removeFileFromDir(oldFileName, _dir);     <-------- Normally, this part should be working
    }
}

And, I solved this bug by adding an else case to Check 1. Here is the new logic:

QFileInfo info(_dir + fileName);
if (info.isFile())
{
    bool isOldFileExist = this->mddb.isFileExistInDir(oldFileName, dir);
    bool isNewFileExist = this->mddb.isFileExistInDir(fileName, dir);

    if(isOldFileExist && !isNewFileExist)
    {
            auto currentState = this->mddb.stateOfFileInDir(fileName, dir);

          // Do not count renames (moves) if files is new added.
          if(currentState != MonitoredDirDb::MonitoredItemState::NewAdded)     <------- Check 1
          {
              // Here categorize files as Moved or MovedAndModified
          }
          else      <--------- Solution is this else case
          {
              // If newly added file overwrites existing file then, consider that file modified
              this->mddb.scheduleFileInDirAs(fileName, dir, MonitoredDirDb::MonitoredItemState::Modified);
          }

          this->mddb.updateEventTimestampOfFileInDir(fileName, dir, QDateTime::currentDateTime());
    }
    else if(isOldFileExist && isNewFileExist) // Ghost file cleanup
    {
        this->mddb.removeFileFromDir(oldFileName, _dir);     <-------- Normally, this part should be working
    }
}

As I said, I considered this edge case. Previous code had a handler. But it looks like, it is not enough. Adding else case solved it completely. But, I need more time to understand why else case solved the issue.

Without else case existing file file.xlsx signaled as new added file by FileMonitoringManager even though it wass added to mddb previously. I'm sure that, it happens when new created file overwrites an existing file. Because, only place where code is marked as NewAdded is FileMonitoringManager::slotOnAddEventDetected(). And debugging confirmed it.

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions