Tornadofx runAsync issue - javafx-8

runAsync {} ui {}
The ui{ } block is triggered sometimes and sometimes not . What causing it .
From my understanding if the task in runAsync { } is a quick task then ui{} doesn't work . Please help. It's kind of frustrating.

This was actually a design flaw in the ui function. It simply attached the passed in function to the setOnSucceeded callback without checking if the task was already complete at this point. This has been corrected in tornadofx-1.7.14-SNAPSHOT, which is available in oss.sonatype.org now. See the README page for information about how to use snapshot releases :)

Related

Synchronous function inside Task or outside - any difference?

Will there be any difference in running a function that is not marked as async and running it inside a Task?
.onChange(of: callState.current) { state in
viewModel.changeNavigation(title: state.controllerTitle) // 1 - outside
Task {
viewModel.changeNavigation(title: state.controllerTitle) // 2 - inside
Task.detached(priority: .background) {
await viewModel.audit(state: state)
}
}
}
onChange is called from MainActor (SwiftUI View).
Both options are executed on the main thread.
Is there any difference in the performance exerted on the main thread and UI?
The difference is how the function runs relative to code around it. With the viewModel.changeNavigation code outside of the task, it will certainly run before any of the code that follows it.
With it inside the task you know that it will run at some point in the future, but you don't have any idea what other code might run before it.
If something else has been sent to the main queue it might execute first. If there are other tasks in the same execution context they could run before that call too.
The performance impact of creating the task and having it work through the scheduler is non-zero, but at user interface speeds probably won't be noticeable.
But you've definitely changed the timing of when the code will run and that may cause race conditions and the like if you're not careful.

Should a function returning a boolean be used in an if statement?

If I have a function call that returns true or false as the condition of an if statement, do I have to worry about Swift forking my code for efficiency?
For example,
if (resourceIsAvailable()) { //execute code }
If checking for the resource is computationally expensive, will Xcode wait or attempt to continue on with the code?
Is this worth using a completion handler?
What if the resource check must make a database call?
Good question.
First off... can a function be used? Absolutely.
Second... should it be used?
A lot of that depends on the implementation of the function. If the function is known (to the person who wrote it) to take a long time to complete then I would expect that person to deal with that accordingly.
Thankfully with a lot of iOS things like that are taken out of the hands of the developer (mostly). CoreData and Network requests normally come with a completion handler. So any function that uses them would also need to be async and have a completion handler.
There is no fixed rule for this. My best advice would be...
If you can see the implementation of the function then try to work out what it’s doing.
If you can’t then give it a go. You could even use the time profiler in Xcode profiler to determine how long it is taking to complete.
The worst that could happen is you find it is slow and then change it for something else.

jBPM signal event does always complete work item

I've implemented a custom workitemhandler which I want to complete only by an external REST call. Therefore the items executeWorkItem() method does NOT call manager.completeWorkItem(workItem.getId(), results); at the end, which is perfectly ok. I've also assigned a signal event to this workitem in my process, which is also called by an external REST call. Both things work as expected, but what I do not understand is that every time I signal the work item, it also automatically completes the work item, which leads to the problem that the process continuous with its regular path AND the signaled one. But the reason for the signal is to interrupt the process to follow ONLY the signaled path path.
The process image to this can be found here http://cl.ly/image/0F3L3E2w2l0j. In this example I signaled the "Fail Transfer" but the rest gets also executed even nothing completed the workitem.
I'm using jBPM 6.1 Final.
Thanks in advance for any help.
Nevermind, I found the reason for this behavior. The custom work item handler implemented
public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
manager.abortWorkItem(workItem.getId());
}
After removing manager.abortWorkItem(workItem.getId());, the process behaves as expected.

How to know Optaplanner solving has ended?

I have initialized and started a solver, I have registered a listener for the best solution change but I would also like to know when solving has ended.
I have configured the logger and it correctly shows when the solver has stopped solving (when the termination condition is met or when it is terminated early). I would like to know when the solver has finished, whichever way it ended.
Here's my current code for listening for best solution changes
solver.addEventListener(new SolverEventListener() {
#Override
public void bestSolutionChanged(BestSolutionChangedEvent bestSolutionChangedEvent) {
//Get the new best solution
}
});
I have gone through the documentation several times but couldn't find what I need. Any ideas? Thanks.
PS: I'm using Optaplanner 6.0.1 final
When the Solver.solve() method returns.
Note when the daemon mode is explicitly set to true, that will only happen if Solver.terminateEarly() is called from another thread. Otherwise it will happen after the Termination says it's done too.

ember.js route render: dom manipulation with setTimeout()?

if i wanted to call a jquery plugin (which inserts a table into the dom, for example) after a view has been rendered, are there a possibilities except doing this with window.setTimeout()?
This code does the job (1ms timeout; thats weird):
Route.HomeRoute = Ember.Route.extend({
renderTemplate: function() {
this.render("home"); // render the home view
window.setTimeout(function() {
$(".tables").insertTables(); // this would add a table
}, 1);
}
})
But this code doesn't work:
Route.HomeRoute = Ember.Route.extend({
renderTemplate: function() {
this.render("home"); // render the home view
$(".tables").insertTables(); // this would add a table
}
});
I know that there's Ember.View.didInsertElement(), but therefore i have to set a callback on the parent View, and was just wondering, why the code example above doesn't work as expected.
Many thanks!
I don't know wether my answer is 100% accurate, but i guess this is how it can be explained:
I guess the problem is, that you think that the render() method does its job synchronously. But this is not the case. Instead it schedules the rendering of the HomeView. The rendering is scheduled into the RunLoop of Ember. In the second example your code schedules the rendering and then immediately tries to access its DOM Elements (i guess .tables is part of the home template). But the View is not rendered at this time! The first example works, because there is 1ms timeout involved. During this timeout the Ember RunLoop will kick in and starts its magic. It performs the rendering and afterwards when the CPU is free again, your timeout function can be called.
Actually what you want to do here is: do something on my DOM, when the View was successfully rendered. This can be done in Ember, without the use of setTimeout. The following code accesses the RunLoop and schedules a function to be performed at the end of the RunLoop.
Ember.run.next(function() {
$(".tables").insertTables(); // this would add a table
});
Here is an article on the RunLoop, which is important to understand, if you want to understand those details of Ember:
- Article by machty
Last but not least: It seams totally awkward to do such DOM Manipulation in the Route. Your Route should always be free, of such things. Element and Selectors and jQuery Plugins should only be used in the View layer. Everything else seems bad. Maybe you want to share more details about why you chose this approach? There is likely a better solution that this one.
The reason why the second example doesn't work is probably due to the Ember.js Run Loop. this.render schedules the dom insertion for later in the current run loop.
DOM insertion is done at the end of the run loop, and by using setTimeout, you are calling the plugin after the run loop ends, therefore guaranteeing that the template was injected into the DOM. (no need for the 1ms, 0ms would probably work)
You might say this run loop thing is very complicated, especially for an Ember.js beginner. The thing is, ideally, it is supposed to be transparent to the app developer. The reason why you are encountering its side effects, is because DOM manipulation should not be handled in the router.
My first reaction was to tell you to use didInsertElement, or any code or hook inside the View, because that's where DOM manipulation should happen. But it seems you are aware of that and cannot use it for some reason (which I can't confirm or deny because I don't have enough information).
My advice to you, try your best to do it in didInsertElement.