This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 238210 - IDE hangs (~40sec) on Unix due to /net/.hg && /net/CVS && /net/.git && /net/.svn checks
Summary: IDE hangs (~40sec) on Unix due to /net/.hg && /net/CVS && /net/.git && /net/....
Status: RESOLVED FIXED
Alias: None
Product: versioncontrol
Classification: Unclassified
Component: Code (show other bugs)
Version: 7.2
Hardware: All Unix
: P2 normal (vote)
Assignee: Ondrej Vrabec
URL:
Keywords: PERFORMANCE
Depends on:
Blocks:
 
Reported: 2013-11-10 22:56 UTC by Vladimir Voskresensky
Modified: 2013-11-22 02:45 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Voskresensky 2013-11-10 22:56:09 UTC
When IDE is reopened with i.e. project versioned by mercurial we observe the following behavior:
- IDE is frozen for ~40 sec if project is located at /net/machine/export/.... path

truss shows that there is hanging "stat" for 
 /net/.hg && /net/CVS && /net/.git && /net/.svn checks

It would be great if versioning can consider all auto mount points as "unversioned" and does not force (by .exists() check) mounting i.e. /net/CVS or /net/.hg etc

masterfs uses for following to skip automounts for some operations.

public static final HashSet<String> AUTOMOUNT_SET = new HashSet<String>(Arrays.asList("set", "shared", "net", "java", "share", "home", "ws", "ade_autofs"));
Comment 1 Vladimir Voskresensky 2013-11-10 22:58:05 UTC
problem is seen when in callstack exists call to DelegatingVCS.hasMetadata.
Could you, please, prepopulate once unversionedParents with known set of never versioned folders and "/" as well.
Comment 2 Vladimir Voskresensky 2013-11-10 23:02:31 UTC
known stacks:
"org.netbeans.modules.versioning.core.VcsVisibilityQueryImplementation"
java.io.File.exists(File.java:806)
org.netbeans.modules.versioning.core.api.VCSFileProxy.exists(VCSFileProxy.java:352)
org.netbeans.modules.versioning.DelegatingVCS.hasMetadata(DelegatingVCS.java:529)
org.netbeans.modules.versioning.DelegatingVCS.getTopmostManagedAncestor(DelegatingVCS.java:173)
org.netbeans.modules.versioning.core.VersioningManager.getOwner(VersioningManager.java:438)
org.netbeans.modules.versioning.core.VcsVisibilityQueryImplementation$RefreshTask.run(VcsVisibilityQueryImplementation.java:281)
org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1432)
org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2042)
Comment 3 Vladimir Voskresensky 2013-11-10 23:02:44 UTC
"RepositoryUpdater.worker"
java.io.File.exists(File.java:806)
org.netbeans.modules.versioning.core.api.VCSFileProxy.exists(VCSFileProxy.java:352)
org.netbeans.modules.versioning.DelegatingVCS.hasMetadata(DelegatingVCS.java:529)
org.netbeans.modules.versioning.DelegatingVCS.getTopmostManagedAncestor(DelegatingVCS.java:173)
org.netbeans.modules.versioning.core.VersioningManager.getOwner(VersioningManager.java:438)
org.netbeans.modules.versioning.core.VersioningManager.getOwner(VersioningManager.java:346)
org.netbeans.modules.versioning.core.filesystems.VCSFilesystemInterceptor.getRefreshInterceptor(VCSFilesystemInterceptor.java:488)
org.netbeans.modules.versioning.core.filesystems.VCSFilesystemInterceptor.listFiles(VCSFilesystemInterceptor.java:385)
org.netbeans.modules.versioning.masterfs.FilesystemInterceptor.refreshRecursively(FilesystemInterceptor.java:146)
org.netbeans.modules.masterfs.ProvidedExtensionsProxy.refreshRecursively(ProvidedExtensionsProxy.java:316)
org.netbeans.modules.masterfs.filebasedfs.fileobjects.FileObjectKeeper.init(FileObjectKeeper.java:146)
org.netbeans.modules.masterfs.filebasedfs.fileobjects.FolderObj.getKeeper(FolderObj.java:669)
org.netbeans.modules.masterfs.filebasedfs.fileobjects.FolderObj.addRecursiveListener(FolderObj.java:682)
org.openide.filesystems.DeepListener.relisten(DeepListener.java:110)
org.openide.filesystems.DeepListener.init(DeepListener.java:86)
org.openide.filesystems.FileChangeImpl.addRecursiveListener(FileChangeImpl.java:264)
org.openide.filesystems.FileUtil.addRecursiveListener(FileUtil.java:390)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$RootsListeners.safeAddRecursiveListener(RepositoryUpdater.java:6195)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$RootsListeners.add(RepositoryUpdater.java:6112)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$AbstractRootsWork.scanSource(RepositoryUpdater.java:5242)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$AbstractRootsWork.scanSources(RepositoryUpdater.java:4956)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$RootsWork.getDone(RepositoryUpdater.java:4661)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Work.doTheWork(RepositoryUpdater.java:3236)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task._run(RepositoryUpdater.java:5689)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task.access$4900(RepositoryUpdater.java:5355)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task$3$1.run(RepositoryUpdater.java:5614)
org.netbeans.modules.parsing.impl.RunWhenScanFinishedSupport.performScan(RunWhenScanFinishedSupport.java:96)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task$3.call(RepositoryUpdater.java:5610)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task$3.call(RepositoryUpdater.java:5606)
org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:176)
org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:360)
org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:74)
org.netbeans.modules.parsing.impl.indexing.RepositoryUpdater$Task.run(RepositoryUpdater.java:5606)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
java.util.concurrent.FutureTask.run(FutureTask.java:262)
org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1432)
org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2042)
Comment 4 Vladimir Voskresensky 2013-11-10 23:03:08 UTC
"VersioningAnnotator.annotationRefresh"
java.io.File.exists(File.java:806)
org.netbeans.modules.versioning.core.api.VCSFileProxy.exists(VCSFileProxy.java:352)
org.netbeans.modules.versioning.DelegatingVCS.hasMetadata(DelegatingVCS.java:529)
org.netbeans.modules.versioning.DelegatingVCS.getTopmostManagedAncestor(DelegatingVCS.java:173)
org.netbeans.modules.versioning.core.VersioningManager.getOwner(VersioningManager.java:438)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider.getOwner(VersioningAnnotationProvider.java:96)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider.access$1200(VersioningAnnotationProvider.java:78)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider$Cache.getCommonOwner(VersioningAnnotationProvider.java:773)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider$Cache.annotate(VersioningAnnotationProvider.java:677)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider$Cache.access$1500(VersioningAnnotationProvider.java:511)
org.netbeans.modules.versioning.core.VersioningAnnotationProvider$Cache$AnnotationRefreshTask.run(VersioningAnnotationProvider.java:794)
org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1432)
org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2042)
Comment 5 Ondrej Vrabec 2013-11-11 10:48:10 UTC
> masterfs uses for following to skip automounts for some operations.
> public static final HashSet<String> AUTOMOUNT_SET = new HashSet<String>(Arrays.asList("set", "shared", "net", "java", "share", "home", "ws", "ade_autofs"));
i found it only in masterfs.BaseFileObjectTestHid. I doubt it will help you if i add the same to our tests.
Comment 6 Vladimir Voskresensky 2013-11-11 16:43:14 UTC
(In reply to Ondrej Vrabec from comment #5)
> > masterfs uses for following to skip automounts for some operations.
> > public static final HashSet<String> AUTOMOUNT_SET = new HashSet<String>(Arrays.asList("set", "shared", "net", "java", "share", "home", "ws", "ade_autofs"));
> i found it only in masterfs.BaseFileObjectTestHid. I doubt it will help you
> if i add the same to our tests.
It was just an example where to get the list. 
masterfs.BaseFileObjectTestHid had to introduce this list, otherwise tests can never finishes due to timeout in Unix systems with automounts.
Comment 7 Vladimir Voskresensky 2013-11-11 16:44:40 UTC
for described problem with /net/CVS etc we need a solution in hasMetadata
Comment 8 Alexander Simon 2013-11-11 16:50:51 UTC
see also bug #225063
Comment 9 Ondrej Vrabec 2013-11-11 17:07:16 UTC
fix: http://hg.netbeans.org/core-main/rev/e2fb44bce792 - adding an option to skip certain folders and not to call File.exists on their possible .hg/.git/... children. Populate those folders with -J-Dversioning.forbiddenFolders="FOLDER_PATH1;FOLDER_PATH2;..."
Comment 10 Vladimir Voskresensky 2013-11-11 18:01:53 UTC
Ondrej, looks great. Users will be happy.

The only comment is about possible race when initialize field
private static Set<String> forbiddenFolders;
Probably can move initialization into 
static {} initialization block. 
Only use System.getProperty, so should be very cheap.
Comment 11 Ondrej Vrabec 2013-11-13 13:35:55 UTC
> The only comment is about possible race when initialize field
> private static Set<String> forbiddenFolders;
what do you mean? That the field will be initialized twice (or more times)? I guess it doesn't matter, does it?
Comment 12 Vladimir Voskresensky 2013-11-13 16:31:16 UTC
(In reply to Ondrej Vrabec from comment #11)
> > The only comment is about possible race when initialize field
> > private static Set<String> forbiddenFolders;
> what do you mean? That the field will be initialized twice (or more times)?
> I guess it doesn't matter, does it?
I mean, that JIT can reorder non volatile field accesses like in 
http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
So, the second thread will pass as non null the check:
if (forbiddenFolders == null) { 
(because already started initialization on the other thread and field is not volatile)
while list can be not completely initialized yet.
Comment 13 Ondrej Vrabec 2013-11-13 17:07:01 UTC
fix: http://hg.netbeans.org/core-main/rev/4d1c2ae363bd
Comment 14 Ondrej Vrabec 2013-11-14 19:33:26 UTC
vladimir, please verify ASAP so i can integrate into 7.4 - if you have no other comments
Comment 15 Vladimir Voskresensky 2013-11-14 19:36:48 UTC
Doing it right now... sorry for the delay, I'm in US and ... you know...
Comment 16 Ondrej Vrabec 2013-11-14 19:42:10 UTC
i will integrate tomorrow so no rush, you have a whole day :-)
Comment 17 Vladimir Voskresensky 2013-11-14 19:50:57 UTC
Ondrej, it works, thanks. The only comment is:
if I specify 
-J-Dversioning.forbiddenFolders="/home/vv159170"
it doesn't check /home/vv159170/CVS, but still checks
/home/CVS
so I have to specify
-J-Dversioning.forbiddenFolders="/home;/home/vv159170"

Please, integrate as is in release74 and improve in trunk. Thanks.
Comment 18 Ondrej Vrabec 2013-11-14 19:56:29 UTC
(In reply to Vladimir Voskresensky from comment #17)
> -J-Dversioning.forbiddenFolders="/home;/home/vv159170"
correct.
> Please, improve in trunk.
I will not, you have to explicitly specify every folder you do not want to scan. I will not traverse the given folders to its ancestors, sounds weird and confusing. Simply list all folders you wish.
Comment 19 Vladimir Voskresensky 2013-11-14 19:59:16 UTC
(In reply to Ondrej Vrabec from comment #18)
> (In reply to Vladimir Voskresensky from comment #17)
> > -J-Dversioning.forbiddenFolders="/home;/home/vv159170"
> correct.
> > Please, improve in trunk.
> I will not, you have to explicitly specify every folder you do not want to
> scan. I will not traverse the given folders to its ancestors, sounds weird
> and confusing. Simply list all folders you wish.
Or, sorry. I thought you can easily break doing "while" and do not deep dive into parent's check if children is forbidden. 
But it looks like you think my understanding is not correct?
Comment 20 Vladimir Voskresensky 2013-11-14 20:01:13 UTC
Ok. I think you are right. It's better to be more flexible and force to specify exactly what to skip. /home is very easy to specify having /home/user.
Nothing extra is expected from you.

Thanks!
Comment 21 Quality Engineering 2013-11-15 03:05:11 UTC
Integrated into 'main-silver', will be available in build *201311150002* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/e2fb44bce792
User: Ondrej Vrabec <ovrabec@netbeans.org>
Log: #238210 - IDE hangs (~40sec) on Unix due to /net/.hg && /net/CVS && /net/.git && /net/.svn checks
do not look for metadata in specific folders where the I/O response for File.exists may take a long time
Comment 23 Alexander Simon 2013-11-15 14:25:47 UTC
The fix introduced a regression in remote VCS TCK:
java.lang.NullPointerException
	at org.netbeans.modules.versioning.VCSOwnerTestCase.testGetOwnerVersioned(VCSOwnerTestCase.java:105)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at org.netbeans.junit.NbTestCase.access$200(NbTestCase.java:97)
	at org.netbeans.junit.NbTestCase$2.doSomething(NbTestCase.java:431)
	at org.netbeans.junit.NbTestCase$1Guard.run(NbTestCase.java:357)
	at java.lang.Thread.run(Thread.java:722)

The test is located in the module remotefs.versioning:
org.netbeans.modules.remotefs.versioning.spi.RemoteVCSTCKTest
Comment 24 Ondrej Vrabec 2013-11-15 14:51:34 UTC
i'm getting:
-do-junit-single:
    [junit] Testsuite: org.netbeans.modules.remotefs.versioning.spi.RemoteVCSTCKTest
    [junit] Tests run: 0, Failures: 0, Errors: 1, Time elapsed: 0.902 sec
    [junit] 
    [junit] Testcase: org.netbeans.junit.NbTestSuite@50f5db13:  Caused an ERROR
    [junit] null
    [junit] java.lang.NullPointerException
    [junit]     at org.netbeans.modules.nativeexecution.api.util.ConnectionManager.isConnectedTo(ConnectionManager.java:247)
    [junit]     at org.netbeans.modules.nativeexecution.api.util.ConnectionManager.connectTo(ConnectionManager.java:323)
    [junit]     at org.netbeans.modules.remotefs.versioning.spi.RemoteVCSTCKTest.setUp(RemoteVCSTCKTest.java:148)
    [junit]     at org.netbeans.junit.NbTestSetup$1.protect(NbTestSetup.java:63)
    [junit]     at org.netbeans.junit.NbTestSetup.run(NbTestSetup.java:68)
    [junit] 
    [junit] 
    [junit] Test org.netbeans.modules.remotefs.versioning.spi.RemoteVCSTCKTest FAILED

i suggest you fix your test first or at least let me know how to run it. BTW, org.netbeans.modules.versioning.masterfs.FileVCSTest passes which leads me to a conclusion you have an error in your test.
Comment 25 Alexander Simon 2013-11-15 14:54:31 UTC
In any way fix cannot be integrated in release74 before remote VCS TCK will fixed.
Comment 26 Alexander Simon 2013-11-15 15:23:44 UTC
The bug is in org.netbeans.modules.versioning.core.Utils, line 103:

String forbidden = System.getProperty("versioning.forbiddenFolders", "");
files.addAll(Arrays.asList(forbidden.split("\\;"))); //NOI18N

Files contains empty string.
Expected:
Files is empty.
Comment 27 Ondrej Vrabec 2013-11-15 15:38:03 UTC
core-main #374b9f0eb8bd
Comment 28 Alexander Simon 2013-11-15 17:37:39 UTC
(In reply to Ondrej Vrabec from comment #22)
> http://hg.netbeans.org/releases/rev/8e24864cea80
> http://hg.netbeans.org/releases/rev/5aa65d98a7f9
> http://hg.netbeans.org/releases/rev/9a235a756f9c

Ondrej,

I see that some of VSC clients were changed.
Is it possible to redo fix without touching clients?

If no, the fix introduces new contract.
It should be described in API and ALL clients should be updated.
Comment 29 Alexander Simon 2013-11-15 17:40:00 UTC
(In reply to Ondrej Vrabec from comment #27)
> core-main #374b9f0eb8bd
Remote VSC TCK was fixed.
Thanks.
Comment 30 Ondrej Vrabec 2013-11-15 17:47:20 UTC
(In reply to Alexander Simon from comment #28)
> I see that some of VSC clients were changed.
> Is it possible to redo fix without touching clients?
Sure, but you would still see some slownesses.
> If no, the fix introduces new contract.
> It should be described in API and ALL clients should be updated.
No public API was changed, all our maintained VCS implementations now have a chance to decide and skip these folders if they wish, no one forces them to do so. Svn, git and mercurial just decided to call a common piece of code in versioning.util.
Comment 31 Alexander Simon 2013-11-15 18:09:30 UTC
(In reply to Ondrej Vrabec from comment #30)
> (In reply to Alexander Simon from comment #28)
> > I see that some of VSC clients were changed.
> > Is it possible to redo fix without touching clients?
> Sure, but you would still see some slownesses.
> > If no, the fix introduces new contract.
> > It should be described in API and ALL clients should be updated.
> No public API was changed, all our maintained VCS implementations now have a
> chance to decide and skip these folders if they wish, no one forces them to
> do so. Svn, git and mercurial just decided to call a common piece of code in
> versioning.util.
Should be updated ADE client (in internal build of Oracle Solaris Studio)?
Comment 32 Ondrej Vrabec 2013-11-15 18:22:24 UTC
> Should be updated ADE client (in internal build of Oracle Solaris Studio)?
It depends how it implements its getTopmostManaged method. I assume it's similar to other VCSs? Does it traverse files to root and call file.exists() on every folder? If so, then it could skip these folders too, otherwise it will freeze on the auto-mount points, yes. But that's ADE's choice and versioning infrastructure doesn't care if it does or not.
Comment 33 Quality Engineering 2013-11-22 02:45:30 UTC
Integrated into 'main-silver', will be available in build *201311220002* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)

Changeset: http://hg.netbeans.org/main-silver/rev/374b9f0eb8bd
User: Ondrej Vrabec <ovrabec@netbeans.org>
Log: #238210 - IDE hangs (~40sec) on Unix due to /net/.hg && /net/CVS && /net/.git && /net/.svn checks
do not keep empty string in the set