From c3dec09d9c14ed8de0c9ea752b7288f01fdde3e3 Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Sun, 20 Nov 2022 12:27:51 +0100 Subject: [PATCH 1/5] add loop for re-trying failed tiles [Take 3] --- src/imageloader.js | 23 +++++++++++++++++++++-- src/openseadragon.js | 2 ++ src/viewer.js | 4 +++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/imageloader.js b/src/imageloader.js index 91d33b50..2dbbb3a8 100644 --- a/src/imageloader.js +++ b/src/imageloader.js @@ -50,12 +50,14 @@ * @param {Function} [options.callback] - Called once image has been downloaded. * @param {Function} [options.abort] - Called when this image job is aborted. * @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete. + * @param {Number} [options.tries] - Actual number of the current try. */ $.ImageJob = function(options) { $.extend(true, this, { timeout: $.DEFAULT_SETTINGS.timeout, - jobId: null + jobId: null, + tries: 0 }, options); /** @@ -87,6 +89,8 @@ $.ImageJob.prototype = { * @method */ start: function() { + this.tries++; + var self = this; var selfAbort = this.abort; @@ -138,6 +142,7 @@ $.ImageLoader = function(options) { jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit, timeout: $.DEFAULT_SETTINGS.timeout, jobQueue: [], + failedTiles: [], jobsInProgress: 0 }, options); @@ -220,7 +225,8 @@ $.ImageLoader.prototype = { }; /** - * Cleans up ImageJob once completed. + * Cleans up ImageJob once completed. Restarts job after tileRetryDelay seconds if failed + * but max tileRetryMax times * @method * @private * @param loader - ImageLoader used to start job. @@ -228,6 +234,9 @@ $.ImageLoader.prototype = { * @param callback - Called once cleanup is finished. */ function completeJob(loader, job, callback) { + if (job.errorMsg != '' && job.image === null && job.tries < 1 + loader.tileRetryMax) { + loader.failedTiles.push(job); + } var nextJob; loader.jobsInProgress--; @@ -238,6 +247,16 @@ function completeJob(loader, job, callback) { loader.jobsInProgress++; } + if (loader.tileRetryMax > 0 && loader.jobQueue.length === 0) { + if ((!loader.jobLimit || loader.jobsInProgress < loader.jobLimit) && loader.failedTiles.length > 0) { + nextJob = loader.failedTiles.shift(); + setTimeout(function () { + nextJob.start(); + }, loader.tileRetryDelay); + loader.jobsInProgress++; + } + } + callback(job.data, job.errorMsg, job.request); } diff --git a/src/openseadragon.js b/src/openseadragon.js index 45e4c8e7..5f40f070 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1354,6 +1354,8 @@ function OpenSeadragon( options ){ maxImageCacheCount: 200, timeout: 30000, useCanvas: true, // Use canvas element for drawing if available + tileRetryMax: 0, + tileRetryDelay: 2500, //INTERFACE RESOURCE SETTINGS prefixUrl: "/images/", diff --git a/src/viewer.js b/src/viewer.js index d963bf14..be6fdef1 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -393,7 +393,9 @@ $.Viewer = function( options ) { // Create the image loader this.imageLoader = new $.ImageLoader({ jobLimit: this.imageLoaderLimit, - timeout: options.timeout + timeout: options.timeout, + tileRetryMax: this.tileRetryMax, + tileRetryDelay: this.tileRetryDelay }); // Create the tile cache From 77bc130636ab01246739f1d92f93b710eed8002c Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Mon, 23 Jan 2023 19:49:43 +0100 Subject: [PATCH 2/5] Add tileRetryMax documentation. --- src/openseadragon.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openseadragon.js b/src/openseadragon.js index 5f40f070..5eb13a39 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -495,6 +495,9 @@ * @property {Number} [timeout=30000] * The max number of milliseconds that an image job may take to complete. * + * @property {Number} [tileRetryMax=0] + * The max number of retries when a tile download fails. By default it's 0, so retries are disabled. + * * @property {Boolean} [useCanvas=true] * Set to false to not use an HTML canvas element for image rendering even if canvas is supported. * From 5d70a807da2814456dabc0159ad9c8b7c6a649ba Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Mon, 23 Jan 2023 19:54:51 +0100 Subject: [PATCH 3/5] fix build error --- src/imageloader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageloader.js b/src/imageloader.js index 2dbbb3a8..85ea7b4c 100644 --- a/src/imageloader.js +++ b/src/imageloader.js @@ -234,7 +234,7 @@ $.ImageLoader.prototype = { * @param callback - Called once cleanup is finished. */ function completeJob(loader, job, callback) { - if (job.errorMsg != '' && job.image === null && job.tries < 1 + loader.tileRetryMax) { + if (job.errorMsg !== '' && job.image === null && job.tries < 1 + loader.tileRetryMax) { loader.failedTiles.push(job); } var nextJob; From f0f12c459e678a36fb8364c6bf1e19181b19ced6 Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Mon, 23 Jan 2023 22:10:23 +0100 Subject: [PATCH 4/5] try fix with check for null and undefined --- src/imageloader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageloader.js b/src/imageloader.js index 85ea7b4c..365c5c79 100644 --- a/src/imageloader.js +++ b/src/imageloader.js @@ -234,7 +234,7 @@ $.ImageLoader.prototype = { * @param callback - Called once cleanup is finished. */ function completeJob(loader, job, callback) { - if (job.errorMsg !== '' && job.image === null && job.tries < 1 + loader.tileRetryMax) { + if (job.errorMsg !== '' && (job.image === null || job.image === undefined) && job.tries < 1 + loader.tileRetryMax) { loader.failedTiles.push(job); } var nextJob; From b4700d28bda8ac551e9372302f4a8a40604c235c Mon Sep 17 00:00:00 2001 From: Dragos Daian Date: Mon, 23 Jan 2023 22:16:05 +0100 Subject: [PATCH 5/5] Also add documentation for tileRetryDelay --- src/openseadragon.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openseadragon.js b/src/openseadragon.js index 5eb13a39..efcd087c 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -498,6 +498,9 @@ * @property {Number} [tileRetryMax=0] * The max number of retries when a tile download fails. By default it's 0, so retries are disabled. * + * @property {Number} [tileRetryDelay=2500] + * Milliseconds to wait after each tile retry if tileRetryMax is set. + * * @property {Boolean} [useCanvas=true] * Set to false to not use an HTML canvas element for image rendering even if canvas is supported. *