Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to cancel ongoing HTTP requests in loaders #23070

Open
wants to merge 7 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/api/en/loaders/Loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ <h3>[property:Object requestHeader]</h3>
The [link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header request header] used in HTTP request. See [page:.setRequestHeader]. Default is empty object.
</p>

<h3>[property:AbortSignal abortSignal]</h3>
<p>
An [link:https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal AbortSignal] instance used to cancel the requests. See [page:.setAbortSignal]. Default is null.
</p>

<h2>Methods</h2>

<h3>[method:undefined load]()</h3>
Expand Down Expand Up @@ -113,6 +118,20 @@ <h3>[method:this setRequestHeader]( [param:Object requestHeader] )</h3>
Set the [link:https://developer.mozilla.org/en-US/docs/Glossary/Request_header request header] used in HTTP request.
</p>

<h3>[method:this setAbortSignal( [param:AbortSignal abortSignal] )</h3>
<p>
[page:AbortSignal abortSignal] - Set the [link:https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal AbortSignal] instance used to cancel the requests.<br/><br />
<strong>Warning:</strong> once the signal has been triggered, the loader will always immediately cancel new requests, you must then provide a new signal (from a new AbortController).
</p>
<code>
const controller = new AbortController();
const loader = new FileLoader();
loader.setAbortSignal(controller.signal);

loader.load(/* .... */);
controller.abort();
</code>

<h2>Source</h2>

<p>
Expand Down
26 changes: 18 additions & 8 deletions examples/jsm/loaders/3DMLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Rhino3dmLoader extends Loader {
loader.setPath( this.path );
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( this.requestHeader );
loader.setAbortSignal( this.abortSignal );

this.url = url;

Expand Down Expand Up @@ -124,6 +125,7 @@ class Rhino3dmLoader extends Loader {

worker._callbacks[ taskID ] = { resolve, reject };

// TODO if abortSignal is defined, listen to it to cancel the worker
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally the abort signal would be handled to "kill" the web worker. having never used web worker I prefer not to try it myself.

worker.postMessage( { type: 'decode', id: taskID, buffer }, [ buffer ] );

// this.debug();
Expand Down Expand Up @@ -671,21 +673,17 @@ class Rhino3dmLoader extends Loader {
// Load rhino3dm wrapper.
const jsLoader = new FileLoader( this.manager );
jsLoader.setPath( this.libraryPath );
const jsContent = new Promise( ( resolve, reject ) => {
jsLoader.setAbortSignal( this.abortSignal );

jsLoader.load( 'rhino3dm.js', resolve, undefined, reject );

} );
const jsContent = jsLoader.loadAsync( 'rhino3dm.js' );

// Load rhino3dm WASM binary.
const binaryLoader = new FileLoader( this.manager );
binaryLoader.setPath( this.libraryPath );
binaryLoader.setResponseType( 'arraybuffer' );
const binaryContent = new Promise( ( resolve, reject ) => {
binaryLoader.setAbortSignal( this.abortSignal );

binaryLoader.load( 'rhino3dm.wasm', resolve, undefined, reject );

} );
const binaryContent = binaryLoader.loadAsync( 'rhino3dm.wasm' );

this.libraryPending = Promise.all( [ jsContent, binaryContent ] )
.then( ( [ jsContent, binaryContent ] ) => {
Expand All @@ -704,6 +702,18 @@ class Rhino3dmLoader extends Loader {

this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );

} )
.catch( ( error ) => {

// on user abort
if ( error.name === 'AbortError' ) {

this.libraryPending = null;

}

throw error;

} );

}
Expand Down
4 changes: 4 additions & 0 deletions examples/jsm/loaders/3MFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class ThreeMFLoader extends Loader {
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( buffer ) {

try {
Expand Down Expand Up @@ -88,6 +90,8 @@ class ThreeMFLoader extends Loader {

const scope = this;
const textureLoader = new TextureLoader( this.manager );
textureLoader.setCrossOrigin( this.crossOrigin );
textureLoader.setAbortSignal( this.abortSignal );

function loadDocument( data ) {

Expand Down
2 changes: 2 additions & 0 deletions examples/jsm/loaders/AMFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class AMFLoader extends Loader {
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( text ) {

try {
Expand Down
2 changes: 2 additions & 0 deletions examples/jsm/loaders/BVHLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class BVHLoader extends Loader {
loader.setPath( scope.path );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( text ) {

try {
Expand Down
27 changes: 18 additions & 9 deletions examples/jsm/loaders/BasisTextureLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ class BasisTextureLoader extends Loader {
load( url, onLoad, onProgress, onError ) {

const loader = new FileLoader( this.manager );

loader.setResponseType( 'arraybuffer' );
loader.setWithCredentials( this.withCredentials );
loader.setAbortSignal( this.abortSignal );

const texture = new CompressedTexture();

Expand Down Expand Up @@ -173,6 +173,7 @@ class BasisTextureLoader extends Loader {

worker._callbacks[ taskID ] = { resolve, reject };

// TODO if abortSignal is defined, listen to it to cancel the worker
worker.postMessage( { type: 'transcode', id: taskID, buffers: buffers, taskConfig: taskConfig }, buffers );

} );
Expand Down Expand Up @@ -221,22 +222,18 @@ class BasisTextureLoader extends Loader {
const jsLoader = new FileLoader( this.manager );
jsLoader.setPath( this.transcoderPath );
jsLoader.setWithCredentials( this.withCredentials );
const jsContent = new Promise( ( resolve, reject ) => {

jsLoader.load( 'basis_transcoder.js', resolve, undefined, reject );
jsLoader.setAbortSignal( this.abortSignal );

} );
const jsContent = jsLoader.loadAsync( 'basis_transcoder.js' );

// Load transcoder WASM binary.
const binaryLoader = new FileLoader( this.manager );
binaryLoader.setPath( this.transcoderPath );
binaryLoader.setResponseType( 'arraybuffer' );
binaryLoader.setWithCredentials( this.withCredentials );
const binaryContent = new Promise( ( resolve, reject ) => {
binaryLoader.setAbortSignal( this.abortSignal );

binaryLoader.load( 'basis_transcoder.wasm', resolve, undefined, reject );

} );
const binaryContent = binaryLoader.loadAsync( 'basis_transcoder.wasm' );

this.transcoderPending = Promise.all( [ jsContent, binaryContent ] )
.then( ( [ jsContent, binaryContent ] ) => {
Expand All @@ -257,6 +254,18 @@ class BasisTextureLoader extends Loader {
this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );
this.transcoderBinary = binaryContent;

} )
.catch( ( error ) => {

// on user abort
if ( error.name === 'AbortError' ) {

this.transcoderPending = null;

}

throw error;

} );

}
Expand Down
2 changes: 2 additions & 0 deletions examples/jsm/loaders/ColladaLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class ColladaLoader extends Loader {
loader.setPath( scope.path );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( text ) {

try {
Expand Down
22 changes: 16 additions & 6 deletions examples/jsm/loaders/DRACOLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ class DRACOLoader extends Loader {
load( url, onLoad, onProgress, onError ) {

const loader = new FileLoader( this.manager );

loader.setPath( this.path );
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( this.requestHeader );
loader.setWithCredentials( this.withCredentials );
loader.setAbortSignal( this.abortSignal );

loader.load( url, ( buffer ) => {

Expand Down Expand Up @@ -165,6 +165,7 @@ class DRACOLoader extends Loader {

worker._callbacks[ taskID ] = { resolve, reject };

// TODO if abortSignal is defined, listen to it to cancel the worker
worker.postMessage( { type: 'decode', id: taskID, taskConfig, buffer }, [ buffer ] );

// this.debug();
Expand Down Expand Up @@ -233,12 +234,9 @@ class DRACOLoader extends Loader {
loader.setPath( this.decoderPath );
loader.setResponseType( responseType );
loader.setWithCredentials( this.withCredentials );
loader.setAbortSignal( this.abortSignal );

return new Promise( ( resolve, reject ) => {

loader.load( url, resolve, undefined, reject );

} );
return loader.loadAsync( url );

}

Expand Down Expand Up @@ -291,6 +289,18 @@ class DRACOLoader extends Loader {

this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );

} )
.catch( ( error ) => {

// on user abort
if ( error.name === 'AbortError' ) {

this.decoderPending = null;

}

throw error;

} );

return this.decoderPending;
Expand Down
6 changes: 5 additions & 1 deletion examples/jsm/loaders/FBXLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class FBXLoader extends Loader {
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( buffer ) {

Expand Down Expand Up @@ -138,7 +139,10 @@ class FBXLoader extends Loader {

// console.log( fbxTree );

const textureLoader = new TextureLoader( this.manager ).setPath( this.resourcePath || path ).setCrossOrigin( this.crossOrigin );
const textureLoader = new TextureLoader( this.manager );
textureLoader.setPath( this.resourcePath || path );
textureLoader.setCrossOrigin( this.crossOrigin );
textureLoader.setAbortSignal( this.abortSignal );

return new FBXTreeParser( textureLoader, this.manager ).parse( fbxTree );

Expand Down
4 changes: 3 additions & 1 deletion examples/jsm/loaders/FontLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class FontLoader extends Loader {
const loader = new FileLoader( this.manager );
loader.setPath( this.path );
loader.setRequestHeader( this.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setWithCredentials( this.withCredentials );
loader.setAbortSignal( this.abortSignal );

loader.load( url, function ( text ) {

let json;
Expand Down
2 changes: 2 additions & 0 deletions examples/jsm/loaders/GCodeLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class GCodeLoader extends Loader {
loader.setPath( scope.path );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( text ) {

try {
Expand Down
7 changes: 5 additions & 2 deletions examples/jsm/loaders/GLTFLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class GLTFLoader extends Loader {
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( this.requestHeader );
loader.setWithCredentials( this.withCredentials );
loader.setAbortSignal( this.abortSignal );

loader.load( url, function ( data ) {

Expand Down Expand Up @@ -314,14 +315,13 @@ class GLTFLoader extends Loader {
path: path || this.resourcePath || '',
crossOrigin: this.crossOrigin,
requestHeader: this.requestHeader,
abortSignal: this.abortSignal,
manager: this.manager,
ktx2Loader: this.ktx2Loader,
meshoptDecoder: this.meshoptDecoder

} );

parser.fileLoader.setRequestHeader( this.requestHeader );

for ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {

const plugin = this.pluginCallbacks[ i ]( parser );
Expand Down Expand Up @@ -2263,9 +2263,12 @@ class GLTFParser {

this.textureLoader.setCrossOrigin( this.options.crossOrigin );
this.textureLoader.setRequestHeader( this.options.requestHeader );
this.textureLoader.setAbortSignal( this.options.abortSignal );

this.fileLoader = new FileLoader( this.options.manager );
this.fileLoader.setResponseType( 'arraybuffer' );
this.fileLoader.setRequestHeader( this.options.requestHeader );
this.fileLoader.setAbortSignal( this.options.abortSignal );

if ( this.options.crossOrigin === 'use-credentials' ) {

Expand Down
1 change: 1 addition & 0 deletions examples/jsm/loaders/HDRCubeTextureLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class HDRCubeTextureLoader extends Loader {
.setPath( scope.path )
.setResponseType( 'arraybuffer' )
.setWithCredentials( scope.withCredentials )
.setAbortSignal( scope.abortSignal )
.load( urls[ i ], function ( buffer ) {

loaded ++;
Expand Down
2 changes: 2 additions & 0 deletions examples/jsm/loaders/IFCLoader.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions examples/jsm/loaders/KMZLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class KMZLoader extends Loader {
loader.setResponseType( 'arraybuffer' );
loader.setRequestHeader( scope.requestHeader );
loader.setWithCredentials( scope.withCredentials );
loader.setAbortSignal( scope.abortSignal );

loader.load( url, function ( text ) {

try {
Expand Down
Loading