Bug 198638 - [ftp][regression] FTPService does improper caching
Summary: [ftp][regression] FTPService does improper caching
Status: RESOLVED FIXED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P1 major (vote)
Target Milestone: 2.0.1   Edit
Assignee: Martin Oberhuber CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords:
Depends on: 195830
Blocks:
  Show dependency tree
 
Reported: 2007-08-02 05:43 EDT by Martin Oberhuber CLA
Modified: 2007-08-02 11:22 EDT (History)
0 users

See Also:
mober.at+eclipse: review? (javier.montalvoorus)


Attachments
Patch to fix FTP statcache issues (9.97 KB, patch)
2007-08-02 07:31 EDT, Martin Oberhuber CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Oberhuber CLA 2007-08-02 05:43:45 EDT
In FTPService.java version 1.30, a cache for FTPHostFile objects was added to the service. That cache has several problems:

 * Cached objects have no maximum lifetime. Even after disconnect + reconnect,
   old objects could still be retrieved from the cache. This imposes two issues:
     1.) it is a memory leak.
     2.) Old outdated objects could be used, which may be fatal for the
         delete() or setReadOnly() operations -- when the remote side has
         modified the file without us knowing.

 * The Hashtable class is being used, which is synchronized all over. This
   is unnecessary overhead, since access to the table is only (and can only)
   happen from critical sections protected by the Mutex. HashMap should be 
   used instead.

 * In internalFetch(), only the FILTERED list of children is added into
   the cache. That's an unnecessary restriction, the UNFILTERED list 
   should be added to the cache instead.

I see the following possibilities for improving / fixing the situation:

1.) Instead of accessing the fileMap in some client methods (download, delete,
    setReadOnly) a proper implementation should be in the getFile() method
    which is used by all of these. Code is then restricted to a single
    location, and can be used by more potential clients.

2.) In order to fix the memory leak / outdating issue, I see two possibilities
    2a) The simpler one is to restrict the cache to a single parent directory
        only. Since in most cases, a LIST command comes before the respective
        action, a cache with depth of a single directory should be sufficient,
        though that needs some testing:
              long _fCachePreviousTimestamp;
              HashMap _fCachePreviousFiles;
        In internalFetch(), always clear the cache before filling it with
        contents of the fresh query:
              _fCachePreviousFiles.clear();
              _fCachePreviousTimestamp = System.currentTimeMillis();
        and add ALL the results, not just the filtered ones
        In getFile(), the timestamp needs to be checked to verify that
        using the cache is still valid. If the cache is too old, it should
        be cleared.
        In disconnect(), the cache should also be cleared to avoid
        unnecessary memory hog.

    2b) The harder one is to keep multiple remote directory queries cached,
        but have a timestamp associated with each of them and ensure they
        are cleaned up (e.g. with a Timer job) after their lifetime expires.
Comment 1 Martin Oberhuber CLA 2007-08-02 07:31:49 EDT
Created attachment 75209 [details]
Patch to fix FTP statcache issues

There were even more issues with the caching:

* Only internalGetFiles() was cached, but not the getFile() queries so the
  cache was actually useless

* case sensitivity was not properly considered, see also bug 198645

* symbolic link file vs. folder treatment was not considered in getFile()

All these issues should be fixed with attached patch.
Please review and commit.
Comment 2 Martin Oberhuber CLA 2007-08-02 07:35:14 EDT
Fix committed, Javier please review:

[198638][198645] Fix FTP caching and case sensitivity issues
   FTPService.java
Comment 3 Martin Oberhuber CLA 2007-08-02 11:22:49 EDT
The statcache must also be cleared on all operations that modify the remote:
Committed change

[198638] Clear ftp statCache on all operations that modify the remote
    FTPService.java