Bug 149188 - Multiple Refresh jobs are scheduled for single selection
Summary: Multiple Refresh jobs are scheduled for single selection
Status: RESOLVED FIXED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P2 normal (vote)
Target Milestone: 1.0   Edit
Assignee: David McKnight CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-29 12:21 EDT by Martin Oberhuber CLA
Modified: 2008-08-13 13:07 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Oberhuber CLA 2006-06-29 12:21:10 EDT
Reproduced with an ssh connection on Windows, but supposedly happens with other connection types too:

Create a new filter for a remote directory e.g. on build.eclipse.org,
  "/home/data/users/moberhuber/downloads-tm/downloads/drops/N20060627-1258"
Select the filter and choose Refresh --> See the contents
Select the filter and choose "Show in Table" --> See the contents

Select the filter and choose Refresh --> now, two refresh jobs are scheduled as the following backtrace shows. This can be seen by placing a breakpoint in SftpFileService.getFile() or SftpFileService.internalFetch().

Thread [Worker-36] (Suspended (breakpoint at line 140 in SftpFileService))	
	SftpFileService.getFile(IProgressMonitor, String, String) line: 140	
	FileServiceSubSystem.getFile(IProgressMonitor, String, String) line: 287	
	FileServiceSubSystem.getRemoteFileObject(String) line: 209	
	FileServiceSubSystem(RemoteFileSubSystem).internalResolveFilterString(IProgressMonitor, String) line: 588	
	FileServiceSubSystem(RemoteFileSubSystem).internalResolveFilterStrings(IProgressMonitor, String[]) line: 414	
	SubSystem$ResolveAbsolutesJob.performOperation(IProgressMonitor) line: 1424	
	SubSystem$ResolveAbsolutesJob(SubSystem$SubSystemOperationJob).run(IProgressMonitor) line: 1332	
	Worker.run() line: 58	
Thread [Worker-39] (Running)	
Thread [Worker-41] (Suspended (breakpoint at line 140 in SftpFileService))	
	SftpFileService.getFile(IProgressMonitor, String, String) line: 140	
	FileServiceSubSystem.getFile(IProgressMonitor, String, String) line: 287	
	FileServiceSubSystem.getRemoteFileObject(String) line: 209	
	FileServiceSubSystem(RemoteFileSubSystem).internalResolveFilterString(IProgressMonitor, String) line: 588	
	FileServiceSubSystem(RemoteFileSubSystem).internalResolveFilterStrings(IProgressMonitor, String[]) line: 414	
	FileServiceSubSystem(SubSystem).resolveFilterStrings(IProgressMonitor, String[]) line: 2214	
	SystemViewFilterReferenceAdapter.internalGetChildren(IProgressMonitor, Object) line: 367	
	SystemViewFilterReferenceAdapter.getChildren(IProgressMonitor, Object) line: 226	
	SystemFetchOperation.execute(IProgressMonitor) line: 175	
	SystemFetchOperation.run(IProgressMonitor) line: 92	
	SystemViewFilterReferenceAdapter(AbstractSystemViewAdapter).fetchDeferredChildren(Object, IElementCollector, IProgressMonitor) line: 1766	
	DeferredTreeContentManager$1.run(IProgressMonitor) line: 207	
	Worker.run() line: 58
Comment 1 Martin Oberhuber CLA 2006-06-29 12:21:57 EDT
Note that the multiple refresh jobs are problematic if the file service is single threaded, thus they should be avoided.
Comment 2 David McKnight CLA 2006-07-13 15:01:17 EDT
I was able to reproduce this problem with SftpFileService but not the others. 
With Sftp, I'm always getting this stack:

	at com.jcraft.jsch.ChannelSftp.stat(Unknown Source)
	at com.jcraft.jsch.ChannelSftp.ls(Unknown Source)
	at org.eclipse.rse.services.ssh.files.SftpFileService.internalFetch(SftpFileService.java:175)
	at org.eclipse.rse.services.files.AbstractFileService.getFilesAndFolders(AbstractFileService.java:45)
	at org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem.getFilesAndFolders(FileServiceSubSystem.java:282)
	at org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem.listFoldersAndFiles(FileServiceSubSystem.java:316)
	at org.eclipse.rse.subsystems.files.core.subsystems.RemoteFileSubSystem.listFoldersAndFiles(RemoteFileSubSystem.java:907)
	at org.eclipse.rse.subsystems.files.core.subsystems.RemoteFileSubSystem.internalResolveFilterString(RemoteFileSubSystem.java:637)
	at org.eclipse.rse.subsystems.files.core.subsystems.RemoteFileSubSystem.internalResolveFilterStrings(RemoteFileSubSystem.java:414)
	at org.eclipse.rse.core.subsystems.SubSystem.resolveFilterStrings(SubSystem.java:2214)
	at org.eclipse.rse.ui.view.SystemViewFilterReferenceAdapter.internalGetChildren(SystemViewFilterReferenceAdapter.java:367)
	at org.eclipse.rse.ui.view.SystemViewFilterReferenceAdapter.getChildren(SystemViewFilterReferenceAdapter.java:226)

  
Comment 3 Martin Oberhuber CLA 2006-07-14 10:08:25 EDT
The problem is reproducable with dstore as well:
 * place a breakpoint in DStoreFileService.getFile()
 * In the Preferences, ensure that "Use deferred queries" Preference is ON
 * Create a new filter e.g. "/folk/mober/mydir"
 * Expand the filter
 * Select the filter and choose "Show in Table"
 * Select the filter and choose "Refresh"

Watch the breakpoint being hit TWICE, by two different workers.

Ssh runs into an exception because the ssh service is not re-entrant; I'm not sure if the dstore service is reantrant and prepared to handle multiple concurrent requests like this.

Anyways, there should be only ONE remote resolve operation for a single filter being expanded.
Comment 4 David McKnight CLA 2006-07-14 12:23:43 EDT
By adding a synchronized on the filter reference adapter's
internalGetChildren() method this seems to work okay.  I checked in the change
- can you see if this works for you too?
Comment 5 Martin Oberhuber CLA 2006-07-17 04:54:20 EDT
The synchronized seems not a good solution, for various reasons:

* internalGetChildren() is a method that calls out to several other classes and 
  methods, including some that may be contributed by extenders of RSE. Making 
  such a "parent method" synchronized is _extremely dangerous_ since it locks
  the object against concurrent access from other threads...
  if user code calls out into the UI thread for instance (e.g. by
  IProgressMonitor.worked(), and the UI thread thinks it needs to access the 
  filter reference adapter, a deadlock might occur.

* Also, the fix does not solve the root problem.
  If I put a breakpoint in DStoreFileService.getFile(), and perform the refresh
  operation, then
  - If deferred queries are _on_, the breakpoint gets hit 2 times
  - If deferred queries are _off_, the breakpoint gets hit 4 times

Thanks to the fix, the breakpoint hits are now serialized (one after the other), but this still means that choosing "refresh" leads to up to 4 queries into the remote system. This may be a performance problem on slow connections.

Asking "Refresh" should refresh the underlying model only _once_ by getting new data from the remote system. Then, all the views should be updated by reading the internal model which has been refreshed already.

I would strongly vote for removing the (synchronized) again because it is too dangerous, unless you can argue the fix is safe.
Comment 6 David McKnight CLA 2006-09-14 12:47:39 EDT
I found a bug that occurred in some cases of getParentPath() which would return the child path.  With that fixed, I only see 1 getFile() call when deferred queries are one and 2 when they're off.
Comment 7 Martin Oberhuber CLA 2006-09-14 12:52:12 EDT
good! Do you think you could get rid of the 2nd query when deferred queries are off too?  - If not this is probably not so much of an issue since I'd like the deferred queries to be the default anyways.
Comment 8 David McKnight CLA 2006-09-14 16:38:23 EDT
I've taken out the ISystemContainer.markStale() call that is in the system table provider flushCache() method.  The actions and events should be taking care of the stale bit, not the table provider.  The prevents the additional query.
Comment 9 Martin Oberhuber CLA 2008-08-13 13:07:09 EDT
[target cleanup] 1.0 M5 was the original target milestone for this bug