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.
Performs the given task when the scan finished. When no background scan is running it performs the given task synchronously. When the background scan is active it queues the given task and returns, the task is performed when the background scan completes by the thread doing the background scan. The API should be stable to NB 6.0.
The new API is a single public method runWhenScanFinished with the same signature as the runUserActionTask method.
Created attachment 41259 [details] diff file
A few comments: 1. How will the caller know if the task returned after completing the work or the task got queued? This can be useful to take further action on the caller side e.g. show wait cursor, progress bar and so on. 2. What is the relationship of the this thread doing the background scan and the thread on which the regular runUserActionTasks() run? Can these two tasks ever run in an interspersed fashion? Will the start of one cancel the other? I think this need to be clarified. 3. In case the caller changes their mind how can they cancel the queed tasks? Does the client have to come up with their own mechanism? What if some kind of object was returned to indicate synchronous vs. queued behavior. Could such object have the API to cancel the queued task?
[Sandip 2]: The background scan runs in the "Java Source Thread" (JST) this is the same thread which performs the tasks registered by factories. When the initial scan is running this tasks wait to the end of initial scan. The difference is the tasks performed by the runUserActionTask which are performed synchronously by the caller thread. The runUserActionTask firstly looks if the JST is doing some task (including initial scan), if so it calls cancel on it (it may take some time before the task ends and releases the java infrastructure lock). Then it acquires the java infrastructure lock and performs synchronously the given task. Finally it releases the java infrastructure lock and canceled task is restarted. When the runUserActionTask is called it stops background scan, after some time it performs synchronously the given task and finally the background scan continues. But actions which need usages database or resolve types should wait when the background scan completes to get a correct state. For this the runWhenScanFinished () is designed. [Sandip 1,3] Currently user has to implement it, I agree that this may be useful. I will add a return value. The problem is with the point 3 which inherently introduces racecondition, but maybe it doesn't mind. The raceconditio is: JST removes task from the queue, thread switch, user's thread cancels the task, thread switch, JST performs even canceled task since in the time of dispatch it was valid. So, the client of runWhenScanFinished cannot rely on such a cancel anyway. The cancel mechanism may be implemented by the task, which needs it, itself. For example if the task computes some data and fills them into a view, it should check some synchronized flag at the beginning of the task, also the fill method should be synchronized and recheck the flag. The proposed cancel on the returned object from runWhenScanFinished can be implemented without racecondition when the cancel will cal cancel on given task. The task's cancel sets some flag canceled which is used to find out if it shoud continue. But in this case the cancel can be called before the task run is called. I believe it's not a problem, right? Conclusion: I agree that the runWhenScanFinished should return result which can be used to find out if the task was queued or performed. I am not sure with the cancel mechanism, I need a feedback if the cancel even with problems mentioned above is good for you.
Does runModificationTask() behaves differently than runUserActionTask() in terms of cancelling the task/initial scan. I am wondering if we need similar API corresponding to runModificationTask(). Is it possible to check the status of background scan without using this API. Another minor suggestion is about API name. I personally think runAfterScan() sounds better than run runWhenScanFinished.
For now I've changed the void runWhenScanFinished (CancellableTask, boolean) to Future<Void> runWhenScanFinished (CancellableTask, boolean). You can ask the future if it's already done Future.isDone(). You can cancel it (the cancel can be called before CancellableTask.run). Future.cancel(). And you can wait to the end of the task using Future.get(). [Deva 1] The CancellableTask.cancel used by runUserActionTask is useless since the task passed to the JS.runUserActionTask are never canceled. They run synchronously and has higher priority then the task registered by the factories. I did the JS.runWhenScanFinished to keep the same semantics, the cancel on the cancelable task in never called. If you call Future.cancel () and the background scan is in progress it removes the deferred task from queue and returns true. If the background scan is already finished and the posted tasks are performed or are already done, the cancel returns false.
Created attachment 41440 [details] Diff file
Sandip agrees with the proposed API. I am going to integrate it.
Checking in apichanges.xml; /cvs/java/source/apichanges.xml,v <-- apichanges.xml new revision: 1.8; previous revision: 1.7 done Checking in nbproject/project.properties; /cvs/java/source/nbproject/project.properties,v <-- project.properties new revision: 1.18; previous revision: 1.17 done Checking in src/org/netbeans/api/java/source/JavaSource.java; /cvs/java/source/src/org/netbeans/api/java/source/JavaSource.java,v <-- JavaSource.java new revision: 1.45; previous revision: 1.44 done Checking in src/org/netbeans/modules/java/source/classpath/GlobalSourcePath.java; /cvs/java/source/src/org/netbeans/modules/java/source/classpath/GlobalSourcePath.java,v <-- GlobalSourcePath.java new revision: 1.8; previous revision: 1.7 done Checking in src/org/netbeans/modules/java/source/usages/RepositoryUpdater.java; /cvs/java/source/src/org/netbeans/modules/java/source/usages/RepositoryUpdater.java,v <-- RepositoryUpdater.java new revision: 1.49; previous revision: 1.48 done Checking in test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java; /cvs/java/source/test/unit/src/org/netbeans/api/java/source/JavaSourceTest.java,v <-- JavaSourceTest.java new revision: 1.11; previous revision: 1.10 done