BZ 827203

Ian Springer ian.springer at redhat.com
Fri Jun 1 15:42:25 UTC 2012


I agree, it's not something we can drop in a base class and fix the 
whole GUI. I think if we were using an MVP framework, that might be 
possible, but unfortunately we missed the boat on that one.

As Jay said, at least we understand the scenarios when the issues occur 
and know how to add code to prevent them once identified.

On 06/01/2012 10:39 AM, Jay Shaughnessy wrote:
>
> It's not obvious to me that this lends itself to a general solution.  
> Although, this latest refinement should go far to battle issues we've 
> seen navigating the tree.  The fast click issues typically have to do 
> with interactions between async server calls and SmartGWT-generated 
> event handling (like onClick and onSelectionChanged handlers).  In 
> other words, the user changes context before we're done setting up the 
> previously requested context's views/infrastructure.
>
> The best solution we've found has been to disable various widgets 
> (tree nodes, tabs, etc) during the critical sections we've been able 
> to identify.   This has proven more effective than trying to detect 
> and then handle a context change.  It also provides feedback to the 
> user that work is being done to service their last action, and 
> prevents unnecessary calls to the server.
>
> As for the detached DOM elements, that can arise from the fast click 
> issue because we generate widgets for the obsolete context.  But in 
> general that is an issue with cleanup code.
>
> So, the strategy is somewhat generic: establish listener, disable 
> widgets, call listener when work is done, enable widgets, but I'm not 
> sure I see a way to apply this in a general way throughout CoreGUI.  
> Maybe other have some thoughts.
>
>
> On 6/1/2012 9:27 AM, Charles Crouch wrote:
>> Can we use this BZ/fix as a basis for a more general solution to 
>> other fast-clicking problems?
>> Can we use it to find other instances of fast-clicking problems?
>> What about tracking down where "detached DOM elements as well, which 
>> is seen in that blotchy area above the JON logo." are coming from 
>> generically?
>>
>> Just trying to see if we can solve more than one problem here
>>
>> ----- Forwarded Message -----
>> From: "ips"<ips at fedoraproject.org>
>> To: rhq-commits at lists.fedorahosted.org
>> Sent: Thursday, May 31, 2012 4:53:13 PM
>> Subject: [rhq] modules/enterprise
>>
>>   
>> modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java 
>> |   46 ++++++----
>>   1 file changed, 29 insertions(+), 17 deletions(-)
>>
>> New commits:
>> commit a92b7bcace3265964f87fb656b45cf3102ad8708
>> Author: Ian Springer<ian.springer at redhat.com>
>> Date:   Thu May 31 17:53:02 2012 -0400
>>
>>      [BZ 827203] prevent infinite auto-switching between auto-group 
>> nodes occurs after fast-clicking between two auto-group nodes 
>> (https://bugzilla.redhat.com/show_bug.cgi?id=827203)
>>
>> diff --git 
>> a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java 
>> b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java 
>>
>> index ff99825..694f8b6 100644
>> --- 
>> a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
>> +++ 
>> b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
>> @@ -1,6 +1,6 @@
>>   /*
>> -fcontext * RHQ Management Platform
>> - * Copyright (C) 2005-2011 Red Hat, Inc.
>> + * RHQ Management Platform
>> + * Copyright (C) 2005-2012 Red Hat, Inc.
>>    * All rights reserved.
>>    *
>>    * This program is free software; you can redistribute it and/or 
>> modify
>> @@ -92,7 +92,6 @@ import 
>> org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.ResourceGro
>>   import 
>> org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.ResourceGroupDetailView;
>>   import 
>> org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.ResourceTreeDatasource.AutoGroupTreeNode;
>>   import 
>> org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.ResourceTreeDatasource.ResourceTreeNode;
>> -import 
>> org.rhq.enterprise.gui.coregui.client.inventory.resource.factory.ResourceFactoryCreateWizard;
>>   import 
>> org.rhq.enterprise.gui.coregui.client.inventory.resource.factory.ResourceFactoryImportWizard;
>>   import 
>> org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
>>   import org.rhq.enterprise.gui.coregui.client.util.Log;
>> @@ -182,17 +181,30 @@ public class ResourceTreeView extends 
>> LocatableVLayout {
>>
>>                           AutoGroupTreeNode agNode = 
>> (AutoGroupTreeNode) selectedRecord;
>>                           selectedNodeId = agNode.getID();
>> -                        getAutoGroupBackingGroup(agNode, new 
>> AsyncCallback<ResourceGroup>() {
>>
>> -                            public void onFailure(Throwable caught) {
>> -                                
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_selection(),
>> -                                    caught);
>> -                            }
>> +                        // [BZ 827203] Disable this view to prevent 
>> fast-click issues. It will get re-enabled when
>> +                        //             the detail resource or group 
>> view is done with its async init and calls
>> +                        //             notifyViewRenderedListeners() 
>> on itself.
>> +                        disable();
>>
>> -                            public void onSuccess(ResourceGroup 
>> result) {
>> -                                renderAutoGroup(result);
>> -                            }
>> -                        });
>> +                        try {
>> +                            getAutoGroupBackingGroup(agNode, new 
>> AsyncCallback<ResourceGroup>() {
>> +                                public void onSuccess(ResourceGroup 
>> result) {
>> +                                    renderAutoGroup(result);
>> +                                }
>> +
>> +                                public void onFailure(Throwable 
>> caught) {
>> +                                    // Make sure to re-enable 
>> ourselves.
>> +                                    enable();
>> +                                    
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_selection(),
>> +                                        caught);
>> +                                }
>> +                            });
>> +                        } catch (RuntimeException re) {
>> +                            // Make sure to re-enable ourselves.
>> +                            enable();
>> +                            
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_selection(), 
>> re);
>> +                        }
>>                       } else {
>>                           // TODO: probably clicked on a subcategory, 
>> do we need a message?
>>                           treeGrid.deselectRecord(selectedRecord);
>> @@ -246,7 +258,7 @@ public class ResourceTreeView extends 
>> LocatableVLayout {
>>       private void getAutoGroupBackingGroup(final AutoGroupTreeNode 
>> agNode, final AsyncCallback<ResourceGroup>  callback) {
>>           final ResourceGroupGWTServiceAsync resourceGroupService = 
>> GWTServiceLookup.getResourceGroupService();
>>
>> -        // get the children tree nodes and build a child resourceId 
>> array
>> +        // get the children tree nodes and build a child resourceId 
>> array
>>           TreeNode[] children = treeGrid.getTree().getChildren(agNode);
>>           final int[] childIds = new int[children.length];
>>           for (int i = 0, size = children.length; (i<  size); ++i) {
>> @@ -262,13 +274,13 @@ public class ResourceTreeView extends 
>> LocatableVLayout {
>>           resourceGroupService.findResourceGroupsByCriteria(criteria, 
>> new AsyncCallback<PageList<ResourceGroup>>() {
>>
>>               public void onFailure(Throwable caught) {
>> -                
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_node(), 
>> caught);
>> +                callback.onFailure(new 
>> RuntimeException(MSG.view_tree_common_loadFailed_node(), caught));
>>               }
>>
>>               public void onSuccess(PageList<ResourceGroup>  result) {
>>                   if (result.isEmpty()) {
>>                       // Not found, create new backing group
>> -                    // the backing group name is a display name 
>> using a unique parentResource-resourceType combo
>> +                    // the backing group name is a display name 
>> using a unique parentResource-resourceType combo
>>                       final String backingGroupName = 
>> agNode.getBackingGroupName();
>>                       ResourceGroup backingGroup = new 
>> ResourceGroup(backingGroupName);
>>                       
>> backingGroup.setAutoGroupParentResource(agNode.getParentResource());
>> @@ -277,7 +289,7 @@ public class ResourceTreeView extends 
>> LocatableVLayout {
>>                       
>> resourceGroupService.createPrivateResourceGroup(backingGroup, childIds,
>>                           new AsyncCallback<ResourceGroup>() {
>>                               public void onFailure(Throwable caught) {
>> -                                
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_create(), 
>> caught);
>> +                                callback.onFailure(new 
>> RuntimeException(MSG.view_tree_common_loadFailed_create(), caught));
>>                               }
>>
>>                               public void onSuccess(ResourceGroup 
>> result) {
>> @@ -299,7 +311,7 @@ public class ResourceTreeView extends 
>> LocatableVLayout {
>>                       
>> resourceGroupService.setAssignedResources(backingGroup.getId(), 
>> childIds, false,
>>                           new AsyncCallback<Void>() {
>>                               public void onFailure(Throwable caught) {
>> -                                
>> CoreGUI.getErrorHandler().handleError(MSG.view_tree_common_loadFailed_update(), 
>> caught);
>> +                                callback.onFailure(new 
>> RuntimeException(MSG.view_tree_common_loadFailed_update(), caught));
>>                               }
>>
>>                               public void onSuccess(Void result) {
>>



More information about the rhq-devel mailing list