Forum OpenACS Q&A: File upload failures

Collapse
Posted by David Gering on
When my users upload files, set_the_usual_form_variables sometimes produces this error: "Error writing content: resource temporarily unavailable" Is it not possible to have concurrent uploads? The full text of the error is below (from server.log):
Error writing content: resource temporarily unavailable
    while executing
"ns_conncptofp $fp"
    invoked from within
"if {![string match "POST" [ns_conn method]] ||  ![string 
match "*multipart/form-data*"  [string tolower $type]] } {
            
            # Return ordinary or no ..."
    invoked from within
"if ![info exists _ns_form] {
        set _ns_form ""
        set method [ns_conn method]
        set type [ns_set iget [ns_conn headers] content-type]
        
        ## MSIE redirecte ..."
    (procedure "ns_getform" line 4)
    invoked from within
"ns_getform"
    invoked from within
"if { [ns_getform] == "" } {
        if $error_if_not_found_p {
            uplevel { 
                ns_returnerror 500 "Missing form data"
                return
            }
        } else {
            return ..."
    (procedure "set_the_usual_form_variables" line 2)
    invoked from within
"set_the_usual_form_variables 0"
Collapse
Posted by David Gering on
I discovered that I can duplicate the error by re-submitting the form while the file is uploading.  So how do you get users to not do that?

I tried showing a page that does an ns_write "Please wait...", and then does the processing. BUT that page does NOT show up on the browser until the processing is finished! Only if I then refresh that page, does it do what I wanted: it prints the words, THEN performs the processing, and then prints the next words.  So how do I make it ALWAYS flush the words before doing the processing???

Collapse
Posted by Jerry Asher on
David,

When I've seen that error come out of AOLserver, it has been the result of a broken connection while downloading something big, a connection where presumably the user has become bored and moved on.  That would fit with your second scenario, where the form is resubmitted while the upload is in progress.  I can't imagine anyway to prevent that without using JavaScript to disable the form submit.

And that's seems to be what ns_conncptofp is complaining of too, that it was trying to copy the content from the connection to a file pointer when the resource went away.  Presumably the resource in question is the connection and not the disk.  To look into this further, you can start looking at nsd/conn.c/ConnCopy.  That routine has two error returns, one after the read, and one after the write.

The read usually does a nonblocking read from the socket, and if I recall, retrying twice after receiving an EWOULDBLOCK (and then waiting a configurable amount of time), and then finally give up. (but I'm not sure about all this.)  So if your conn goes away for more than the timeout period but is coming back, presumably you've got a pretty flaky connection to begin with.

My question, if you don't click submit again, do you still have the problem while uploading?

Collapse
Posted by Michael Feldstein on
One of the problems here is clearly interface. The file upload feature violates Jakob Neilsen's first usability heuristic: Make the status of the system visible to the user. Ideally, you should have some sort of an upload progress bar that tells people how far along the upload is. If they see that the upload (or download) is working, they'll be less inclined to keep pressing that button.
Collapse
Posted by Carl Coryell-Martin on
Dang,  here at civilution, we put together an AOLserver module to
fix this problem with large uploads.  We tweak some of the
timing loops to make it much more tolerant of pauses in the
upload.  The code isn't released yet, and the person who wrote it
is unavailable till monday.  Since this is the third thread about
this in as many weeks, I'll push to get something out early next
week.

Cheers

Collapse
Posted by Luke Pond on
If you're sending the top of the page ("Please wait, uploading in progress...") back using ns_write, there is no problem with flushing on the server side.  However, Internet Explorer has a strange behavior that you may not know about:  if the connection is still open, it won't perform the initial rendering of the page until it has received at least X bytes (where X is something like 200 or 300).  Try adding a few lines of HTML comments to the initial string you send back, and see if that takes care of your problem.
Collapse
Posted by David Gering on
Luke, I tested your theory by doing an ns_write, then pausing for 2 seconds, then doing another ns_write. IE displayed nothing unless the first ns_write contained ~300 characters.

However, if I apply this trick to file uploads by writing 300 characters before doing set_the_usual_form_variables, IE displays the new page only about halfway through the upload process. That still gives users plenty of time to click Submit again. Anyone know why this latency occurs?

Perhaps, using javascript to throw up a message box that says "wait" is the only idiot-proof solution???

Carl Coryell-Martin, I sure would like to have that robust uploading module!