ICEfaces
  1. ICEfaces
  2. ICE-8760

ace:fileEntry - Issue when uploading large files in IE7

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: EE-3.0.0.GA_P01, 3.2
    • Fix Version/s: 3.3
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      IE7, IE8/9 Compat Mode
    • Assignee Priority:
      P2
    • Salesforce Case Reference:
    • Workaround Exists:
      Yes
    • Workaround Description:
      Hide
      Use the application technique of the pushed full update that is canceled by the upload response script. This can be further tweaked in the fileEntryListener by limiting it to only happen with the appropriate IE user-agent, only happening with a sufficiently large upload size, and adjusting the delay time for the push.
      Show
      Use the application technique of the pushed full update that is canceled by the upload response script. This can be further tweaked in the fileEntryListener by limiting it to only happen with the appropriate IE user-agent, only happening with a sufficiently large upload size, and adjusting the delay time for the push.

      Description


      When uploading larger files (approx 1gb in size) via the ace:fileEntry component in IE7 or IE8/9 Compat Mode the upload completes correctly on the server side. The issue is that the client isn't updated with the required information, as in the file input isn't cleared and the success message isn't shown.




        Activity

        Hide
        Arran Mccullough added a comment - - edited

        I've uploaded two files to the iceads1 server (P:\Users\arran\Case 11732) to help in reproducing this issue.
        (Restricted to icesoft-internal-developers group)

        Show
        Arran Mccullough added a comment - - edited I've uploaded two files to the iceads1 server (P:\Users\arran\Case 11732) to help in reproducing this issue. (Restricted to icesoft-internal-developers group)
        Hide
        Arran Mccullough added a comment - - edited

        Attached test case that reproduces the issue.

        Steps:

        • Load welcomeICEfaces.jsf in IE7 or IE8/9 Compat mode.
        • Upload a file around 1gb in size.
        • Once the upload is completed it will show a log on the server side. But no update is seen on the client.
        • Including the push jar helps to show the progress but it still does not update on the final completion.
        Show
        Arran Mccullough added a comment - - edited Attached test case that reproduces the issue. Steps: Load welcomeICEfaces.jsf in IE7 or IE8/9 Compat mode. Upload a file around 1gb in size. Once the upload is completed it will show a log on the server side. But no update is seen on the client. Including the push jar helps to show the progress but it still does not update on the final completion.
        Hide
        Mark Collette added a comment -

        Initially I was seeing the form upload capturing javascript being re-rendered due to the FixViewState code, so I disabled that code and still see this problem.

        In some cases, when the page is getting updated there is a javascript exception, but that's not the case when it's not updating.

        The server is preparing the DOM updates response, but the client's iframe onload handler is not getting called with the response.

        Show
        Mark Collette added a comment - Initially I was seeing the form upload capturing javascript being re-rendered due to the FixViewState code, so I disabled that code and still see this problem. In some cases, when the page is getting updated there is a javascript exception, but that's not the case when it's not updating. The server is preparing the DOM updates response, but the client's iframe onload handler is not getting called with the response.
        Hide
        Mark Collette added a comment -

        Installed and ran Wireshark on the server, capturing network traffic between the IE client machine and the OS X server, and found that the xml updates are being transmitted from the server and acknowledge by the client. That is, the packets for the response are receiving their ACK. So, definitely the response is being sent by the server, it's just a question of what the client application is doing with the xml updates response.

        I added a timer that would periodically check the hidden iframe for the response xml, in case the response was being received by the browser but maybe the iframe onload wasn't getting called for whatever reason. With the smaller uploads, that completely work, the polling would find the response in the DOM right after the iframe's onload would fire. So, doubly working right. But in the large file scenario with no iframe onload, the polling would never find it either.

        From Wireshark I saw that the server push with the push id, and the client post to get the progress percent file were using different sockets, so that worried me that with those two plus the file upload we were exceeding the max 2 sockets, which might somehow becausing the file upload POST response to get dropped or ignored. So I took out the POSTs for the progress percent file, which should bring the sockets count down by one, and leave the progress in indeterminate mode. But that didn't fix it. So I commented out all icepush code use in the fileEntry javascript and removed the icepush jar, so that it should just be the one upload socket. But that didn't fix it.

        I did notice from Wireshark that the server was sending a FIN flag, which means that the data is over and the socket is being closed. Investigating that pointed to the keepalive time being exceeded, so in case the response was being discarded on a closed socket, I reconfigured my tomcat 7.0.23 to have keepAliveTimeout="-1" and so disable the keepalive timing out, and keep the socket open indefinitely. In Wireshark I could see then no more FIN flag. But that didn't fix it.

        Show
        Mark Collette added a comment - Installed and ran Wireshark on the server, capturing network traffic between the IE client machine and the OS X server, and found that the xml updates are being transmitted from the server and acknowledge by the client. That is, the packets for the response are receiving their ACK. So, definitely the response is being sent by the server, it's just a question of what the client application is doing with the xml updates response. I added a timer that would periodically check the hidden iframe for the response xml, in case the response was being received by the browser but maybe the iframe onload wasn't getting called for whatever reason. With the smaller uploads, that completely work, the polling would find the response in the DOM right after the iframe's onload would fire. So, doubly working right. But in the large file scenario with no iframe onload, the polling would never find it either. From Wireshark I saw that the server push with the push id, and the client post to get the progress percent file were using different sockets, so that worried me that with those two plus the file upload we were exceeding the max 2 sockets, which might somehow becausing the file upload POST response to get dropped or ignored. So I took out the POSTs for the progress percent file, which should bring the sockets count down by one, and leave the progress in indeterminate mode. But that didn't fix it. So I commented out all icepush code use in the fileEntry javascript and removed the icepush jar, so that it should just be the one upload socket. But that didn't fix it. I did notice from Wireshark that the server was sending a FIN flag, which means that the data is over and the socket is being closed. Investigating that pointed to the keepalive time being exceeded, so in case the response was being discarded on a closed socket, I reconfigured my tomcat 7.0.23 to have keepAliveTimeout="-1" and so disable the keepalive timing out, and keep the socket open indefinitely. In Wireshark I could see then no more FIN flag. But that didn't fix it.
        Hide
        Mark Collette added a comment -

        Now we're going to see if in the mode with pushed progress if we can hook into the 100% progress notification to call some code to refresh the page, or call an ICEfaces javascript API to update the page, so that we can force the page to automatically update on it's own. We want to make sure we're still in the same view / window scopes, and I don't think that a typical refresh keeps the same view scope. I'll prototype a hack, and then we'll refine it and tie it into ace:ajax and ace:fileEntry integration, so that apps can control exactly what they're doing on the progress callback.

        Show
        Mark Collette added a comment - Now we're going to see if in the mode with pushed progress if we can hook into the 100% progress notification to call some code to refresh the page, or call an ICEfaces javascript API to update the page, so that we can force the page to automatically update on it's own. We want to make sure we're still in the same view / window scopes, and I don't think that a typical refresh keeps the same view scope. I'll prototype a hack, and then we'll refine it and tie it into ace:ajax and ace:fileEntry integration, so that apps can control exactly what they're doing on the progress callback.
        Hide
        Mark Collette added a comment -

        Prototyping the fix worked, but there was no easy way of automatically updating only the relevant portion of the page. It required application knowledge of what to force updating. Yes, the whole body could be updated, but that can cause sections of the page that are client-side to lose their state. So, I then investigated the idea of using ace:ajax or properties on fileEntry to allow for specifying callback functions for the upload begin, completion, and 100% progress, which would allow applications to use this fix as well as do anything else they'd like to before, after and during an upload. This idea has a lot of merit as a feature on its own. The problem is that without multi-file-upload in place, people are using several fileEntry components together in a single form, and it's really the javascript in the form that handles the whole upload, so there's an awkward many-to-one relationship where we can configure the many, but the one does the work.

        So I came up with a much simpler, and completely application fix with no fileEntry code changes required. Since the above mentioned fix requires the 100% progress notification, it seems reasonable to require server push for this fix as well. Essentially, the fileEntryListener kicks off a 10 second delayed server push, with flagging set so that the next pushed render will flip the rendered flag on a panelGroup so that its parent will get fully updated. Placement of the panelGroup will control exactly what gets updated. If there are distinct regions of the page to force updated, then several panelGroups, all tied to the same rendered property in the bean can then accomplish this. The fileEntryListener will also use JavaScriptRunner to send back in the upload response some javascript that will keep the server push from doing the full update. So, assuming working browsers, there will be two postbacks after the uplaod that don't really do anything, and assuming IE with a large file, then there will be one postback that does the full update. I'll attach the files from showcase that I've modified to demonstrate this work-around.

        Show
        Mark Collette added a comment - Prototyping the fix worked, but there was no easy way of automatically updating only the relevant portion of the page. It required application knowledge of what to force updating. Yes, the whole body could be updated, but that can cause sections of the page that are client-side to lose their state. So, I then investigated the idea of using ace:ajax or properties on fileEntry to allow for specifying callback functions for the upload begin, completion, and 100% progress, which would allow applications to use this fix as well as do anything else they'd like to before, after and during an upload. This idea has a lot of merit as a feature on its own. The problem is that without multi-file-upload in place, people are using several fileEntry components together in a single form, and it's really the javascript in the form that handles the whole upload, so there's an awkward many-to-one relationship where we can configure the many, but the one does the work. So I came up with a much simpler, and completely application fix with no fileEntry code changes required. Since the above mentioned fix requires the 100% progress notification, it seems reasonable to require server push for this fix as well. Essentially, the fileEntryListener kicks off a 10 second delayed server push, with flagging set so that the next pushed render will flip the rendered flag on a panelGroup so that its parent will get fully updated. Placement of the panelGroup will control exactly what gets updated. If there are distinct regions of the page to force updated, then several panelGroups, all tied to the same rendered property in the bean can then accomplish this. The fileEntryListener will also use JavaScriptRunner to send back in the upload response some javascript that will keep the server push from doing the full update. So, assuming working browsers, there will be two postbacks after the uplaod that don't really do anything, and assuming IE with a large file, then there will be one postback that does the full update. I'll attach the files from showcase that I've modified to demonstrate this work-around.
        Hide
        Mark Collette added a comment -

        icefaces3/samples/showcase/showcase/src/main/java/org/icefaces/samples/showcase/example/ace/file/FileEntryBean.java

        icefaces3/samples/showcase/showcase/src/main/webapp/resources/examples/ace/fileentry/fileentry.xhtml

        Show
        Mark Collette added a comment - icefaces3/samples/showcase/showcase/src/main/java/org/icefaces/samples/showcase/example/ace/file/FileEntryBean.java icefaces3/samples/showcase/showcase/src/main/webapp/resources/examples/ace/fileentry/fileentry.xhtml

          People

          • Assignee:
            Mark Collette
            Reporter:
            Arran Mccullough
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: