[neon] Async loading on form [message #1733423] |
Fri, 27 May 2016 11:13 |
Nejc Gasper Messages: 55 Registered: July 2014 |
Member |
|
|
Hello, me again
We want some data to load after the main form loads asynchronously.
What we tried is this inside execLoad and execPostLoad
Jobs.schedule(() -> ModelJobs.schedule(() -> buildDocumentTree(),
ModelJobs.newInput(ClientRunContexts.copyCurrent())),
Jobs.newInput().withRunContext(ClientRunContexts.copyCurrent()));
But this code also seems to block UI when called from execLoad. I might be doing something wrong or just plain misreading the case. What would be the proper way to load form elements in a delayed fashion (the service that returns this data is very slow so we don't want the whole form to be blocked for seconds, but only - if possible - that part of the UI).
edit: added some info above
[Updated on: Fri, 27 May 2016 11:23] Report message to a moderator
|
|
|
Re: [neon] Async loading on form [message #1733516 is a reply to message #1733423] |
Sun, 29 May 2016 11:30 |
Daniel Wiehl Messages: 1 Registered: May 2016 |
Junior Member |
|
|
Hi Nejc
You can achieve this solely in 'execLoad' method by using one of the following approaches:
The first approach is similar to yours and fully asynchronously:
// Load document data asynchronously (not in model thread)
Jobs.schedule(() -> {
final byte[] document = BEANS.get(IDocumentService.class).loadDocument(documentId);
// Update document field in model thread
ModelJobs.schedule(() -> getDocumentField().setValue(document),
ModelJobs.newInput(ClientRunContexts.copyCurrent())
.withName("Updating document field [document={}]", documentId));
} , Jobs.newInput()
.withName("Loading document asynchronously [document={}]", documentId)
.withRunContext(ClientRunContexts.copyCurrent()));
The second approach blocks the model thread until loaded the document. However, by waiting on a blocking condition, the model job's mutex is released for the time of loading the document. When finally loaded the document, the model thread is signalled to continue execution.
This approach might be useful if you like to stay in the handler until the document is loaded.
// Create a blocking condition to wait until the document is loaded
IBlockingCondition documentLoadedCondition = Jobs.newBlockingCondition(true);
// Load document data asynchronously (not in the model thread)
IFuture<byte[]> future = Jobs.schedule(() -> BEANS.get(IDocumentService.class).loadDocument(documentId),
Jobs.newInput()
.withName("Loading document asynchronously [document={}]", documentId)
.withRunContext(ClientRunContexts.copyCurrent()))
.whenDone((event) -> documentLoadedCondition.setBlocking(false), null);
// Wait until the document is loaded.
// By using a blocking condition, the model job's mutex is released for the time of loading the document,
// which allows other model jobs of this session to run. Also, the UI layer is instructed to transport data to the UI,
// meaning that this model job does not block the UI for the time of loading the document.
documentLoadedCondition.waitFor(ModelJobs.EXECUTION_HINT_UI_INTERACTION_REQUIRED);
// Update the document field with the document loaded.
// Please note, that the current model job acquired the mutex anew upon being signalled to continue.
getDocumentField().setValue(future.awaitDoneAndGet());
I hope this helps, or please let us know otherwise.
Best Regards
Daniel
|
|
|
Powered by
FUDForum. Page generated in 0.03414 seconds