Зависание браузера / сервера при асинхронной загрузке нескольких файлов? - PullRequest
0 голосов
/ 09 мая 2020

На это, вероятно, есть простой ответ, но я его не знаю:

Проблема в том, что я загружаю несколько файлов через XMLHttpRequests, вызывая это из a for l oop. При этом просматриваются файлы, которые необходимо загрузить (вся папка с использованием webkitdirectory). Эта часть работает, если у меня нет большого количества файлов, но у меня их может быть до 300, а может и не больше 1000. Я получил исходный код из проекта Github здесь:

UploadFolder , но я немного отредактировал его для своих нужд. Я думаю, что критический код в основном тот же.

После некоторой предварительной обработки появляется al oop, который выполняет итерацию по списку файлов для загрузки и вызывает функцию для загрузки файлов на сервер:

for (var i = 0; i < picker.files.length; i++) {
    var file = picker.files[i];
    if (processflag[i] == false) {
        let lineitem = statusitem(file, "Skipped (.hidden file)");
        listing.insertAdjacentHTML('beforeend', lineitem);
    }
    else {
    sendFile(file);
    }
}

Функция sendfile довольно длинная, поэтому я только что включил, вероятно, ключевые части:

sendFile = function(file) {

     var timestamp  = picker.dataset.timestamp;
     var formData = new FormData();

     // Set post variables 

     requestcounter = requestcounter + 1;
     formData.set('timestamp', timestamp);
     formData.set('counter', requestcounter);
     formData.set('total', total); 
     formData.set('webkitpath', file.webkitRelativePath);
     formData.set('file', file); // One object file


     var request = new XMLHttpRequest();

     request.responseType = 'json';

     // HTTP onload handler

     request.onload = function() {

         if (request.readyState === request.DONE) {

              if (request.status === 200) {

                 console.log(request.response);

                 // Does a bunch of post-processing stuff here
                 // .....
                 // .........

             }
             else {
                 // issue with request
             }
         }
     }

     // Do request
     request.open("POST", '/OrthancDev/UploadFolder');
     request.send(formData);
}

HTML не так критично.

<div class="picker">
    <input type="file" id="picker" name="fileList" webkitdirectory multiple data-timestamp = "">
</div>

, вероятно, самая важная часть, метка времени устанавливается динамически.

На стороне сервера есть довольно сложная обработка POST с использованием PHP, а также выполнение некоторых установочных двоичных файлов, таких как:

        $proc = proc_open(path_to_executable',[

        1 => ['pipe','w'],
        2 => ['pipe','w'],
        ],$pipes);
        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        proc_close($proc);
        . . . .

и перемещение загрузки в папку на сервере:

move_uploaded_file($file_tmp, $upload_path);

POST на сервер включает в себя:

-----------------------------19160542578905591423661131170
Content-Disposition: form-data; name="timestamp"
2020-05-09-15-44-36
-----------------------------19160542578905591423661131170
Content-Disposition: form-data; name="counter"
24
-----------------------------19160542578905591423661131170
Content-Disposition: form-data; name="total"
25
-----------------------------19160542578905591423661131170
Content-Disposition: form-data; name="webkitpath"
POST_T1_FS_TSE_SAG_2MM_12001/IM-0009-0025.dcm
-----------------------------19160542578905591423661131170
Content-Disposition: form-data; name="file"; filename="POST_T1_FS_TSE_SAG_2MM_12001/IM-0009-0025.dcm"
Content-Type: application/dicom

Кстати, делать загруженные файлы также go в каталог / tmp на сервере?

Проблема в том, что с небольшим набором файлов, скажем, примерно 8, все работает нормально, но с большим количеством файлов ( например, даже всего 25), лоб ser или сервер "виснет". Я запускаю все на сервере MAMP, используя Apache, и журнал Apache выглядит нормально, как и журнал PHP, я не вижу там никаких ошибок.

Он отправляет номер из AJAX запросов в быстрой последовательности.

Я не знаком с вкладкой «Время» в инструментах разработки FF, но к моменту выполнения последнего запроса время «Заблокировано» показывает 1,38 с. Похоже, что все файлы загружаются на сервер, но после этого браузер не отвечает на этот виртуальный хост.

Я предполагаю, что это может иметь какое-то отношение к последовательному запуску такого количества асинхронных запросов. Я мог бы попробовать сделать эти запросы синхронно и посмотреть, не займет ли это слишком много времени, или использовать какое-то обещание, или ограничить количество активных asyn c запросов, но я не уверен, как это сделать.

Я не уверен, что это проблема на стороне сервера. Размер отдельных файлов составляет около 1 МБ, но может быть больше, а вся папка составляет около 256 МБ, но может и больше.

Очевидно, это проблема на стороне сервера. Существует процесс, запускающий исполняемый файл, который, кажется, вешает сервер и, следовательно, браузер:

$proc = proc_open($exec,[
    1 => ['pipe','w'],
    2 => ['pipe','w'],
],$pipes);
. . . .

Это занимает около 30 секунд для запуска из командной строки, но похоже, что все файлы отправляются на сервер и сохранен, так что похоже, что последний процесс вызывает проблему.

Вывод для этого из CLI:

XMIT: .........................................................................
I: Received Store Response (Success)
I: Sending file: /Users/sscotti/Desktop/newtelerad2/dicomtemp/DEV01/2020-05-10-05-44-14/UC5457343/T1_TSE_SAGITTAL_2MM_6001/IM-0003-0021.dcm
I: Converting transfer syntax: Little Endian Explicit -> Little Endian Explicit
I: Sending Store Request (MsgID 18, MR)

но примерно 300x, 1 для каждого файла . Было бы неплохо, если бы был хороший способ проанализировать вывод из STDOUT (например, I, W, E)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...