UIThread not shutting down after closing browser with multiple Runnables currently beeing executed [message #1799125] |
Fri, 30 November 2018 08:20 |
Thomas Lorenz Messages: 4 Registered: November 2018 |
Junior Member |
|
|
Hi guys,
this is my very first post in this discussion board and I hope you therefore excuse any possible misunderstandings.
I'm working on a RAP application in SWT_COMPATIBILITY-mode which is used by 50+ people simultaneously. It happens that we need to start our server once in a week because it runs out of memory because of left open UIThreads.
I set up a sample project based on the hello-world RAP plugin-project where I try to simulate that behavior. I know that a Thread.sleep executed in the UIThread makes absolutely no sense usually, but I want to force the application to run several Runnables in different Threads at the same time.
What the sample application does:
1. set up SWT compatibility
2. set up UISessionListener
3. set up Display.disposeExec
4. create button that triggers a asyncExec on the display with a long-running Runnable
When I start the application, open one instance in the browser, start the Runnable and immediately close the browser while the asyncExec is still running everything behaves OK. The Runnable finishes and then the disposeExec and beforeDestroy are called and in the end the UIThread vanishes.
That works for up to 6 tabs in my browser (start Runnable in all tabs and then close browser).
The problem starts to occur when using 7 Runnables in 7 tabs. It seems that only 6 Runnables can be executed at a time and the 7th is just executed after the first has finished. When I close the browser within the time where all Runnables are triggered the application remains in an undefined state. The disposeExec and beforeDestroy methods are just called for one Thread and 6 UIThreads stay open and never get closed.
Steps to reproduce:
1. open browser with my application in 7 tabs
2. press the button within each tab
3. close the browser while Runnables are still running
I'm using the following setup:
- Eclipse IDE for RCP and RAP developers, Version: 2018-09 (4.9.0) Build id: 20180917-1800.
- RAP 3.7
- Firefox 63.0
- Ubuntu 18.04.1 LTS
- Intel® Core™ i5-4200U CPU @ 1.60GHz × 4
- 8 GB RAM
In the following please find the source code:
public class BasicApplication implements ApplicationConfiguration {
public void configure(Application application) {
Map<String, String> properties = new HashMap<String, String>();
properties.put(WebClient.PAGE_TITLE, "Hello RAP");
application.addEntryPoint("/hello", BasicEntryPoint.class, properties);
application.setOperationMode(OperationMode.SWT_COMPATIBILITY);
}
}
public class BasicEntryPoint extends AbstractEntryPoint {
int displayHash = 0;
@Override
protected void createContents(Composite parent) {
displayHash = Display.getCurrent().hashCode();
RWT.getUISession().addUISessionListener(new UISessionListener() {
@Override
public void beforeDestroy(UISessionEvent event) {
System.out.println(String.format("%x - beforeDestroy", displayHash));
}
});
Display.getCurrent().disposeExec(new Runnable() {
@Override
public void run() {
System.out.println(String.format("%x - disposeExec", displayHash));
}
});
Button button = new Button(parent, SWT.PUSH);
button.setText("PUSH");
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
if(!Display.getCurrent().isDisposed()) {
System.out.println(String.format("%x - before asyncExec", displayHash));
Display.getCurrent().asyncExec(new Runnable() {
@Override
public void run() {
System.out.println(String.format("%x - before sleep", displayHash));
//a lot of work to do
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%x - after sleep", displayHash));
}});
System.out.println(String.format("%x - after asyncExec", displayHash));
}
else {
System.out.println(String.format("%x - display disposed", displayHash));
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
}
I would really appreciate if someone could help me.
Thanks in advance!
Thomas
[EDIT]
I can also reproduce this with Chrome.
And it's also the same behavior when using 7 browser windows and starting the Runnables...
[EDIT]
I think somehow the UIThread of the 7th tab is already blocked while the other 6 Runnables are executed because the widgetSelected() of the 7th tab is not called until the first Runnable finishes.
[EDIT]
I realized that I can reproduce this issue with even simpler code.
I start the Thread.sleep directly within the witchedSelected-method of the Button and the same problem occurs when I start 7 tabs and push the button.
It seems like the framework can only handle 6 UIThreads running in parallel.
I don't know enough about multithreading but shouldn't the scheduler switch between the threads?
public class BasicEntryPoint extends AbstractEntryPoint {
@Override
protected void createContents(Composite parent) {
Button button = new Button(parent, SWT.PUSH);
button.setText("PUSH");
button.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println("PUSH");
try {
Thread.sleep(30000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
}
}
[Updated on: Tue, 04 December 2018 11:45] Report message to a moderator
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.02462 seconds