From 09d32951dee3cd301eae8174fea77169a59d6c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Thu, 18 Jun 2026 07:17:52 +0400 Subject: [PATCH] =?UTF-8?q?v2.0.8:=20retry=20=D0=B4=D0=BE=203=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B7,=20=D1=87=D0=B0=D0=BD=D0=BA=D0=B8=2060KB,=20=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=8C=D1=88=D0=B5=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/templates/upload.html | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/site/templates/upload.html b/site/templates/upload.html index 57c5c45..142d1c1 100644 --- a/site/templates/upload.html +++ b/site/templates/upload.html @@ -60,7 +60,7 @@
Nubes - Сверка договоров v2.0.7 + Сверка договоров v2.0.8
@@ -172,21 +172,35 @@ } var b64 = btoa(b64Chunks.join('')); var checksum = SparkMD5.ArrayBuffer.hash(buffer); - var CHUNK = 55 * 1024; // меньше запросов → меньше HTTP/2 ошибок + var CHUNK = 60 * 1024; // ближе к лимиту 64KB → меньше чанков var totalChunks = Math.ceil(b64.length / CHUNK); var uploadId = 'u' + Date.now().toString(36) + Math.random().toString(36).substr(2, 7); var done = 0; console.log('uploadFileChunked: ' + file.name + ' b64=' + b64.length + ' chunks=' + totalChunks + ' uploadId=' + uploadId); + function fetchWithRetry(url, body, retries) { + retries = retries || 3; + return fetch(url, { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(body) + }).catch(function(e) { + if (retries > 0) { + console.log('retry ' + url + ' (' + retries + ' left): ' + e.message); + return new Promise(function(r) { setTimeout(r, 1000); }).then(function() { + return fetchWithRetry(url, body, retries - 1); + }); + } + throw e; + }); + } + function sendChunk(i) { if (i >= totalChunks) { console.log('finalize: ' + uploadId); - fetch('/v2/finalize', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({upload_id: uploadId, filename: file.name, total: totalChunks, checksum: checksum}) - }).then(function(r) { + fetchWithRetry('/v2/finalize', {upload_id: uploadId, filename: file.name, total: totalChunks, checksum: checksum}) + .then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }).then(function(data) { @@ -197,18 +211,15 @@ } var piece = b64.substring(i * CHUNK, (i + 1) * CHUNK); console.log('chunk ' + i + '/' + totalChunks + ' send ' + piece.length + ' bytes'); - fetch('/v2/chunk', { - method: 'POST', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({upload_id: uploadId, index: i, total: totalChunks, data: piece}) - }).then(function(r) { + fetchWithRetry('/v2/chunk', {upload_id: uploadId, index: i, total: totalChunks, data: piece}) + .then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }).then(function(data) { if (!data.ok) { reject(new Error(data.error)); return; } done++; if (onProgress) onProgress({pct: Math.round(done / totalChunks * 100), done: done, total: totalChunks}); - setTimeout(function() { sendChunk(i + 1); }, 3000); // дать HTTP/2 стримам закрыться + setTimeout(function() { sendChunk(i + 1); }, 3000); }).catch(function(e) { reject(e); }); } sendChunk(0);