Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Listgrid behaviour after unrecoverable failure

    FF: 13.0.1
    SGWT: 3.0 nightly

    Is it default behaviour of Listgrid to retry the fetch request if the server responds with an unrecoverable error?

    The listgrid keeps trying to retrieve the dataset, I guess this is because no rowCount is returned. Am I doing something wrong? This behaviour freezes my browser and floods my server.

    JSON Server response:
    Code:
    {"response":{"status":-1,"data":"Database server is not reachable"}}
    Client code:
    Code:
    final ListGrid listGrid = new ListGrid();
    Button b = new Button("Ophalen"){{
    	addClickHandler(new ClickHandler() {
    		@Override
    		public void onClick(ClickEvent event) {
    			listGrid.fetchData();
    		}
    	});
    }};
    layout.addMember(b);
    
    listGrid.setAutoFetchData(false);
    listGrid.setCanEdit(true);
    listGrid.setStopOnErrors(true);
    listGrid.setDataSource(DataSource.get(ds));

    #2
    I think I found the answer myself, when you look at DataSource.js:8240 there is a line which decides what the endrow of dsResponse should be, that assumption is valid only on status 0. When you send an unrecoverable error to the listgrid in this situation it will receive a response which says it should have 1 row (the error message), but there is no record data! So the listgrid issues another request, resulting in a deadlock loop.

    Can you please solve this issue? Something like the code below should be sufficient:
    Code:
              var status = rpcResponse.status;
                
    	        dsResponse.endRow = (status>0)? dsResponse.startRow + Math.max(0, data.length):0;
    	        dsResponse.totalRows = (status>0)? Math.max(dsResponse.endRow, data.length):0;
    Last edited by dencel; 27 Jul 2012, 14:15.

    Comment


      #3
      This analysis doesn't make sense to us - code in ResultSet.js already handles this case (fetchRemoteDataReply). It seems like there must be more involve in the scenario you're hitting than you think, and it may be a usage issue rather than a framework issue.

      Comment


        #4
        You're correct, the result was not correctly evaluated because of missing jsonPrefix and jsonSuffix in the response, these are not empty by default.

        Comment


          #5
          Hello IsoMorphic-team, I changed my response to include the jsonPrefix and jsonSuffix, but this issue still remains. When I debug the smartclient code I see that status is never set in de dsresponse. There is a code snippet in RPCManager.js:3627
          Code:
          if (response.results && !request.isRestRequest) {
          // this makes status, data, startRow, endRow, etc available directly on
          // "rpcResponse"/"dsResponse", so it's not necessary to use eg
          // "response.results.data"
          // XXX: "results" is still a String at this point for XML REST requests,
          // so we really, really DON'T want to do this for such requests - if we
          // do, the response will end up with one new attribute per letter of text,
          // like 0: "<", 1: "r", 2: "e", 3: "s", 4: "p", 5: "o", 6: "n" ... etc ...
          isc.addProperties(response, response.results);
          }
          But I think this is valid for JSON REST requests (the response data IS evaluated after stripping off the jsonPrefix and jsonSuffix)

          Comment


            #6
            I wrote a small example to illustrate this problem:
            Code:
            public class Test2 implements EntryPoint{
            
            	@Override
            	public void onModuleLoad() {
            		Layout layout = new VLayout();
            		layout.setWidth100();
            		layout.setHeight100();
            		final ListGrid listgrid = new ListGrid();
            		listgrid.setAutoFetchData(false);
            		DataSource ds = new RestDataSource();
            		ds.setJsonPrefix("while(true){}//");
            		ds.setJsonSuffix("var a=5/0;");
            		ds.setDataProtocol(DSProtocol.POSTMESSAGE);
            		ds.setDataFormat(DSDataFormat.JSON); 
            		ds.setDataURL("error.json");
            		OperationBinding fetch = new OperationBinding();
            		fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
            		fetch.setDataFormat(DSDataFormat.JSON); 
            		fetch.setDataURL("error.json");
            		ds.setOperationBindings(fetch);
            		DataSourceField field = new DataSourceIntegerField("id");
            		field.setPrimaryKey(true);
            		ds.setFields(field);
            		
            		listgrid.setDataSource(ds);
            		layout.addMember(listgrid);
            		Button button = new Button("fetch");
            		button.addClickHandler(new ClickHandler() {
            			@Override
            			public void onClick(ClickEvent event) {
            				listgrid.fetchData();
            			}
            		});
            		layout.addMember(button);
            		
            		layout.draw();
            	}
            
            }
            error.json:
            Code:
            while(true){}//[{"response":{"status":-1,"data":"Database server is not reachable"}}]var a=5/0;
            Put a breakpoint on RPCManager.js:3627
            response.status is 0 and this code block is skipped.

            Comment


              #7
              Could you clarify what you're saying is wrong - are you saying that a malformed response from the server produces an infinite loop of requests?

              Comment


                #8
                My apology for my rubbish explanation; another try:

                In the example above;this is what I observe when I click on the fetch button:
                1. Listgrid Posts an JSON request to error.json to retrieve the data requested.
                2. The contents of error.json is returned, which is a valid markup for a general exception (status is -1 and data contains the error message and the response is wrapped with the jsonPrefix and the jsonSuffix defined in the RestDataSource).
                3. The response is parsed by the listgrid and the error message with the message in the data field is displayed.
                4. Listgrid issues another fetch request,starts over at 1. This results in an infinite request loop.

                This is what I see when I debug RPCManager.js and DataSource.js:
                1. The response from error.json is returned and at some point delivered to performTransactionReply in RPCManager.js. RPCManager@3529 strips off jsonPrefix and jsonSuffix and evaluates this stripped data to transaction.results RPCManager@3530
                2. The RPCResponse is created and the initial status is set to transaction.status which is undefined RPCManager@3593, data is set to the to the j'th index of transaction.results @3608
                3. Status is defaulted to 0, because response.status is null, RPCManager@3615
                4. RPCManager@3627 is skipped, because the datasource is a RestDataSource
                5. The response is handed over to handleJSONReply, RPCResponse{status:0,data: response:{status:-1,data:"Database server is not reachable"}}
                6. Data is selected DataSource.js@8220/8227, DSResponse is created DataSource.js@8234, dsResponse is {status:0,startRow:0,endRow:1,totalRows:1,data:"Database server is not reachable"}
                7. DsResponse is handed off to Listgrid which expects 1 row of data, but sees none, new request is issued.

                Point 4 is essential, if RPCManager@3627:
                Code:
                if (response.results && !request.isRestRequest) {
                is changed to
                Code:
                if (response.results && (!request.isRestRequest||(request.isRestRequest && request.dataFormat=="json")) {
                Everything should be fine, for as far as I can see. Status will be set to -1 copied from response.results, from RPCManager@3635

                This is as clear as I can get.

                Comment


                  #9
                  Is there any update on this? Did you track it down?

                  Comment


                    #10
                    We've just made a change which we believe will address this - please try the next nightly build (3.0p branch or 3.1d branch) and let us know if you continue to have issues with it

                    Thanks
                    Isomorphic Software

                    Comment


                      #11
                      I see this infinite loop behaviour as well. Same scenario but I'm using smartgwt 3.1p_2012_12-06. Is this fix in this version?

                      Comment


                        #12
                        Solved

                        I had the same problem with a SelectItem. I'm using SmartGwt 3.0

                        I just changed my response to include totalRows and it worked. Now, it shows the warn dialog once and does not retry the request in a loop.

                        Code:
                        {"response": {"status": -1, "data": "Error Message...", "totalRows": 0}}

                        Comment

                        Working...
                        X