Disable Button......almost there...

Im looking at the new disable button in vaadin 6.7

http://demo.vaadin.com/sampler-6.7.0.beta1/#ButtonDisableOnClick

This is similar to my one I made myself… and, though it works, as with my own implementation, there is an issue.

Navigate to the page above, and click the two save buttons in rapid succession. The two buttons will reenable a few seconds after each other. They should reenable with the same time difference that which you originally clicked. What is happening is this…


User                         Web browser                    Vaadin Server

Button 1 Click ------->Disable button 1 -----> process button 1 request
Button 2 Click ------->Disable Button 2                  | 
                                                      button1 request complete    
                            Enable Button 1 <----------------/
                            Button 2 Request----------->process button 2 request.
                                                       button 2 request complete.
                            Enable button 2<-----------------/

What happens, is the button 1 request, and button 2 requests are handled one after another. What needs to happen is as soon as button 2 is clicked, a second request is sent to the server, so that processing of button 1 requests and button 2 requests can be made concurrently. In otherwords, Button 2’s event that it has been clicked should not wait until button 1’s request has been processed.

An alternative way of handling this, (if the current framework might not support this type of concurrent processing), would be that when buttons are pressed while the server is busy, those events are stored away, so when control passes back from the server, all events that have been made during the time it was busy, can be passed back to the server in one big chunk, rather than taking each event on its own.

That’s just (maybe a bit too simple?) example code, the click listener simply does Thread.sleep(3000), which locks the server request.

If you have similar functionality where the click operation takes long, you could use ProgressIndicator. Actually, the
ProgressIndicator example
does exactly that, although it doesn’t use the automatic disabling of the buttons when clicked.

The code , with the ‘Thread.sleep(3000)’ demonstrates the problem perfectly.

I understand that the server is blocking any more requests, while it competes the task of sleeping for 3 seconds. However, I would like a mode of operation where this locking does not happen, and that buttons will invoke events on the server even while the server is busy.

im not even sure if this is possible… But its just something to think about for a possible future release.

Please read the second paragraph in my previous post.

That anyhow depends on what you use the setDisableOnClick() for. You can use it for many purposes and starting a long-lasting task is just one of them. You can use it just as well to open a sub-window, panel, or do many other things.

I’ve made a demonstration app here:
http://www.tebmsoftware.co.uk/DisableButton

The program will take 30 seconds or so to start, so be patient. the reason for this is below.

The program, shows 15 buttons on screen. The buttons are attached to a button.clicklistener, however all this click listener does is reenable the button. There is no thread.sleep() in the button.clicklistener; the click listener works fast.

There is, however, a servlet filter that has a thread.sleep(5000), to delay each request comming in by 5 seconds… this is to emulate a slow, or congested network. please note this filter delays each individual HTTP request, rather than the buttons click event.

To demonstrate the problem, click buttons 1 to 10 on the screen quickly in turn. these buttons will be disabled as part of the new disable button functionality.

What should happen, is when the first request returns, button 0 should be re-enabled.
Events for the [b]
[u]

[/u]several
[/b] buttons that were clicked during the time button 0 was been processed (say buttons 1,2,3,4,5), should then be sent as a [b]
[u]

[/u]single
[/b] http request. So, when this second request returns, those clicked buttons during the time button 0 was pressed, should reenable all at once.

HOWEVER…

What actually happens, is each button reenables one by one with 5 seconds delay between… , showing that each button’s request uses its own http request.

I have made a demo program, of what should happen: Here
http://www.tebmsoftware.co.uk/CorrectDisableButton

This program also uses a 5 second filter… However, if a button is pressed during active communication, its event is queued up, and sent with other events as soon as the current active communication is complete.

As a suggestion to fix this… Looking at the VAADIN source , in ApplicationConnection.sendPendingVariableChanges(), it appears that immediate events are sent as a ‘burst’ mode if communications is active… However, these burst modes aren’t buffered up, but each is sent individually. Maybe this part of VAADIN can be improved to have a burst queue which burst events are added to, and sent as a big group when active communication is complete, rather than individually?

created ticket for this issue. http://dev.vaadin.com/ticket/7705