Bug #1389
closedOnly 10 dialogs possible
0%
Description
Hello,
We have an Wt application, where we use a dialog box (WDialog) for login. If more then 10 browser connections open the dialog box, the application hangs and no more connections are possible.
You can reproduce the problem with the HelloWt - Example and the following change:
void HelloApplication::greet()
{
/*
- Update the text, using text input into the nameEdit_ field.
*/
greeting_setText("Hello there, " + nameEdit_>text());
WMessageBox::show("Hello", nameEdit_->text(), Ok); <<<<<<------------
}
Then you can make 10 connections to the hello-Application and click the "Greet Me" button, without clicking the Ok button in the message box. With the 10th click you will get only a loading indicator instead of the message box. At this point no more other connections to helloWt are possible. It makes no difference, if you use one browser with 10 tabs or 10 browsers on different machines. The only thing you can do is to restart helloWt.
Can you tell me, what i can do to get my application working with more dialog boxes?
I use Wt 3.2.1 RC (Windows) with the isapi connector for our application and with helloWt i have tested also Wt 3.2.2 p1 (Windows) with the http connector.
Updated by Wim Dumon over 12 years ago
- Status changed from New to Resolved
See http://www.webtoolkit.eu/wt/doc/reference/html/classWt_1_1WDialog.html#details
The static method WMessageBox::show(...) works synchronously (i.e. calling exec() of WDialog). Do not use WDialog::exec() (here called indirectly), it blocks a thread until exec() returns, so when 10 users have a dialog shown (default #threads in Wt is 10), your server cannot process anything else anymore.
So don't use that static method, but create a new WMessageBox, call WDialog::show() on it, and uses the reject(), accept(), ... signals to receive user feedback and to close the dialog.
BR,
Wim.
Updated by Herbert Zenz over 12 years ago
Calling show() instead of exec() is a workaround for some cases.
But in my case - a loginbox - I have to wait for the logindata, before I start the real application. So I have to use exec().
On the other side WDialog::exec() is a documented method of Wt. But if I use this method, I risk a deadlock in my server. In a internet application I can not control, how many users open a dialog at the same time. The problem at this point is not, that only 10 (or #threads) dialogboxes are possible. The problem is that after the 10th (#threads) dialogbox the Wt server is in a deadlock. I can close all 10 boxes and nothing works. The sessions, which have no dialog open, do not work anymore and shows the loading indicator. The only thing I can do, is restarting and then all data in all session will be lost. I think this is a big problem in Wt, which has to be solved.
From my point of view a resolution can be a wait lock for a thread, so that only one session will be blocked, until another session closes the dialog and the thread gets available.
Best regards
Herbert
Updated by Wim Dumon over 12 years ago
The use of exec() can always be replaced by the WDialog::show() method. Why do you think this is not possible in your case? Can you demonstrate based on some (pseudo?) code?
The deadlock as you describe it, should indeed not exist, and if it does, it is a bug that has to be fixed. The recursive event loop should be terminated when the session times out. But bear in mind that (using the default configuration) a Wt session only times out after 10 minutes. Can you confirm that Wt does not recover after 10 minutes?
Your remarks on exec() are correct: you should not use it when you have concurrent users. The manual warns for this:
This solution has the drawback that it is not scalable to many concurrent sessions, since for every session with a recursive event loop, a thread is locked.
I'm preparing a patch to the manual that stresses that exec() is not recommended, and also added a usage example for the asynchronous method.
Wim.
Updated by Herbert Zenz over 12 years ago
Hello,
OK - it is possible to use show() instead of exec() but it has many disadvantages. In my case I've worked for a day to transfer the code:
- The widgets cannot be allocated on the stack. So the heap has to be used and it will be fragmented
- You have to make the variables, you set before show()/exec(), accessible from the method connected to the button.
- The code of one compact method has to be distributed to two methods
OK - not nice - but now it works.
In the HelloWt Example I have set 3 and 12 in the configuration, so that I have not wait 1o min, before I can say, its a deadlock. After opening the 3th messagebox the connections hangs - as expected. After 12 sec (or more) the connections are still hanging. Then I closed the browser with the 3 tabs and waited 12+ sec. After starting a new browser a connection is not possible. I've made this test with Windows XP and for this platform I can confirm: it's a deadlock. But you can try it yourself. Perhaps I've done something wrong.
BR
Herbert
Updated by Wim Dumon over 12 years ago
Updated by Koen Deforche over 12 years ago
- Status changed from Resolved to Closed
- Assignee set to Wim Dumon