Delay after uploading large files with JQuery BlueImp uploader

I can successfully upload large files (verified up to 8GB) via the BlueImp JQuery Uploader plugin.

My PHP settings:

upload_max_filesize 8192M
post_max_size 8192M
max_execution_time 200
max_input_time 200
memory_limit 8192M

      

The problem I am facing is that when large files (2GB or more) finish downloading, the progress bar freezes at 100% and takes a significant amount of time to "complete". I'm not sure what's going on with the post-processing, except that together they are merging the files.

I tried adjusting the block size in the UploadHandler.php file and it seems to improve slightly as it grows (e.g. 10MB to 500MB chunks), but the delay still exists. There seems to be no improvement when disabling downloads (0) and I'm not sure about the possible ramifications of that.

In a 2gb file, the delay is about 20 seconds, but in a 4gb file it is about 2 minutes. 7gb file takes about 3-4 minutes and sometimes time. This results in the user waiting without realizing what is happening when the progress bar is 100% finished by that point.

Does anyone have any idea what this might be, or how to fix it? I suspected that the file in / tmp might be copied rather than moved, but as far as I can tell, there is no sign of this in the php file.

Boosting the CPU and RAM on my VM server improves things a bit, although running the "top" command during this process shows that the CPU and RAM do not look very depleted (0-2% versus 90-100% at actual load).

Thank you very much in advance.

+3


source to share


3 answers


After a lot of troubleshooting and debugging this issue, I've found what I believe is the cause and the best solution / solution. Its a bit "hacky" (Im amateur dev!), So I'm open to any suggestions for improving this, although it seems to work for me.

The files downloaded from the client are actually downloaded to this temporary location on the server: / tmp / systemd -private-random-number-httpd.service-random-number / tmp / sess_php-session-ID

After the client-side download is complete, the UI progress bar reaches 100% and remains that way while the server processes the files.

Server-side processing involves moving (copying and then deleting) a file from the above / tmp location to the appropriate blueimp location. (Assuming the "user_dirs" parameter is enabled / true in the blueimp options, the default is / var / www / html / server / php / files / php-session-id /).

This copying process can take a significant amount of time, especially for files larger than 2 GB or so. When the server finishes processing, blueimp fires the "fileuploaddone" callback, and the UI is refreshed to complete.

My goal was to provide an interactive UI at this point (instead of hanging 90% like the other workaround). My environment is capable of very large downloads (10gb +), so I didn't find it acceptable not to provide user feedback that there could be several minutes of file processing (assuming the site crashed and closed the browser, etc.).

My workaround:

The first problem I ran into was that there didn't seem to be a blueimp callback for the moment when the file upload finished on the client side and server processing starts. So I worked around it by creating a function (in main.js) to render my custom "div handler" after data.loaded matches data.total:

$('#fileupload').bind('fileuploadprogressall', function (e, data) { console.log(data); 
if (data.loaded == data.total) { 
setTimeout(function(){
$("#processwarn").fadeTo(300, 1);
},3000);
}})

      



My custom div that is below the progress bar information is another php page refreshed every few seconds (using ajax.load) and calculates the total file size of all files in the current load folder of the session (total directory size doesn't seem to give exact results):

// Calculate size of files being processed
$filePath = "/var/www/html/server/php/files/*php-session-id*/";

$total = 0;
$d = new RecursiveIteratorIterator(
  new RecursiveDirectoryIterator($filePath), 
  RecursiveIteratorIterator::SELF_FIRST
);

foreach($d as $file){
  $total += $file->getSize();
}

// Convert to readable format
if ($total >= 1073741824)
{
    $total = number_format($total / 1073741824, 2) . ' GB';
}
elseif ($total >= 1048576)
{
    $total = number_format($total / 1048576, 2) . ' MB';
}
elseif ($total >= 1024)
{
    $total = number_format($total / 1024, 2) . ' KB';
}
elseif ($total > 1)
{
    $total = $total . ' bytes';
}
elseif ($total == 1)
{
    $total = $total . ' byte';
}
else
{
    $total = '0 bytes';
}

// Display spinner gif and size of file currently being processed
echo "<img src=\"img/spinner.gif\" height=\"20px\" width=\"20px\">&nbsp;&nbsp;Please wait, processing files: &nbsp;&nbsp;$total";

      

The result looks something like this:

div handling

Edit: (after some additional work) - added a loading progress bar instead:

boot boot bars

Additional point noted during testing:

With blocking enabled (for example, for 1gb (maxChunkSize: 1000000000)), the problem almost disappears, as the processing time decreases dramatically for the user, since the "copy" processing occurs at the chunking point (every 1gb in this example). When final processing takes place, the server only has to "overwrite" / copy the last remaining 1gb.
Because of this, I also experienced faster overall load times. In hindsight, this might be an easier / more efficient solution for many.

0


source


I don't know much about this, I search on google and I found some, I think it might help you.

Typically, the "onError" event is fired when an exception occurs on the server or client. In this situation, no exception is thrown until the server itself shuts down.

One of the possibilities is to monitor the download status and set a timeout or JavaScript counter when an event is loaded, which will cancel the download after a set time limit.

All upload statuses and error codes are displayed here - http://help.infragistics.com/NetAdvantage/jQuery/2013.1/CLR4.0?page=igUpload_Using_Client_Side_Events.html



You can track them using the fileStatus argument when loading the event.

Link to help you

0


source


What could it be :

jQuery FileUpload logs the request progress event. This is the event when the browser is sending data to the server, not a confirmation event from the server. There is a delay between the browser send and the acknowledging server. See Can the onprogress function be added to jQuery.ajax () using xhrFields? for two events. However, I could not solve this for me and used a workaround, so I cannot fully validate this assumption.

How to solve the problem :

Use the browser debug tools and set a breakpoint here in your code to get an idea of ​​the variables available: https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L372

Once you are sure what you want to see, your best bet is to print the information using console.log and check the browser console output.

Work roundabout

If you are only wondering if all downloads have finished and show the user that something else is going on, you can check the stop / execute events as well as the upload ('active') file , see here: Completing a Multiple File Upload

0


source







All Articles