Open mx990 opened 11 months ago
In order to resolve the situation, I would suggest the following remedies:
tryPriorityReadOnly(...)
instead of tryReadOnly(...)
to at least (attempt to) cancel other readers, although this currently only affects the validation job,asyncExec(...)
,I am happy to discuss possible solutions and help in implementing them.
I'm running into a similar issue in the case of a long-running validator and AbstractEObjectHover
's getHoverRegion
method. The behavior I'm seeing is that hovering over the editor while the validator is running will cause the UI to lock up, as the validator is holding a lock and the getHoverRegion
call requests a read-only lock on the UI thread.
Please note that the underlying EMF model is not threadsafe, and there's no such thing as read-only access to the model. Each getter may or may not cause a modification - being it the instantiation of a multi-valued list or an attempt to resolve a proxy, loading a resource into the resource set. Code may attempt to access or modify adapter lists, etc. That's why exclusive access is necessary to safeguard against random bugs.
Do you know if your long-running validation periodically checks the cancel indicator?
Please note that the underlying EMF model is not threadsafe, and there's no such thing as read-only access to the model. Each getter may or may not cause a modification - being it the instantiation of a multi-valued list or an attempt to resolve a proxy, loading a resource into the resource set. Code may attempt to access or modify adapter lists, etc. That's why exclusive access is necessary to safeguard against random bugs.
I am painfully aware of these limitations in EMF. That is why my suggestions focused on keeping the UI responsive despite the lock, rather than removing the (exclusive) lock itself.
Do you have an opinion on how to improve the current situation in Xtext?
My long-running validator does not check the cancel indicator, and if relevant it is really calling out to an external program by creating a process object.
I agree with @mx990 above - in my case, I don't really care if hover info is broken while validation is running, so long as the UI doesn't lock up. Alternatively, maybe I shouldn't be using a validator for the stuff I'm doing?
Alternatively, maybe I shouldn't be using a validator for the stuff I'm doing?
That's hard to tell without knowing what you are doing specifically. Launching a process is certainly not something that I'd expect for a FAST
validation.
My validator is marked as EXPENSIVE
, so it only runs when the user explicitly requests it.
In the meantime, I bodged together a solution by subclassing DefaultCompositeHover
and adding some state to my validator that indicates whether it is currently running. When the validator is running, my DefaultCompositeHover
subclass returns null
from getHoverRegion
.
When an
XtextDocument
is updated usingmodify(...)
, listeners on the UI thread are notified about the change. The same happens whenreadOnly(...)
or one of its derivatives had to reconcile the state before the operation.XtextDocumentLocker.notifyModelListenersOnUiThread()
then blocks the UI thread waiting for a lock usingtryReadOnly(...)
. This happens when it is not already running in the UI-thread, so it re-acquires the lock inside anasyncExec(...)
call on the UI thread.If there is a long-running operation holding the lock, this blocks the UI thread until the operation is completed, causing the UI to be unresponsive in the meantime. Since locks are actually always exclusive, this also happens for contending read operations.
This is also somewhat related to https://github.com/eclipse/xtext/issues/2470, where the current behavior of
notifyModelListenersOnUiThread()
has also been identified as a potential cause for deadlocks.