Skip to content

Commit

Permalink
feat(fetch-client): add retry functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
AshleyGrant committed May 29, 2018
1 parent 345edea commit d16447a
Show file tree
Hide file tree
Showing 8 changed files with 557 additions and 122 deletions.
35 changes: 20 additions & 15 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
System.config({
defaultJSExtensions: true,
transpiler: false,
paths: {
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},

map: {
"aurelia-polyfills": "npm:aurelia-polyfills@1.1.1",
"npm:aurelia-polyfills@1.1.1": {
"aurelia-pal": "npm:aurelia-pal@1.0.0"
}
}
});
System.config({
defaultJSExtensions: true,
transpiler: false,
paths: {
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},

map: {
"aurelia-pal": "npm:aurelia-pal@1.8.0",
"aurelia-pal-browser": "npm:aurelia-pal-browser@1.8.0",
"aurelia-polyfills": "npm:aurelia-polyfills@1.1.1",
"npm:aurelia-pal-browser@1.8.0": {
"aurelia-pal": "npm:aurelia-pal@1.8.0"
},
"npm:aurelia-polyfills@1.1.1": {
"aurelia-pal": "npm:aurelia-pal@1.8.0"
}
}
});
200 changes: 103 additions & 97 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,97 +1,103 @@
{
"name": "aurelia-fetch-client",
"version": "1.3.1",
"description": "A simple client based on the Fetch standard.",
"keywords": [
"aurelia",
"http",
"ajax",
"fetch"
],
"homepage": "http://aurelia.io",
"bugs": {
"url": "https://github.com/aurelia/fetch-client/issues"
},
"license": "MIT",
"author": "Rob Eisenberg <rob@bluespire.com> (http://robeisenberg.com/)",
"main": "dist/commonjs/aurelia-fetch-client.js",
"typings": "dist/aurelia-fetch-client.d.ts",
"repository": {
"type": "git",
"url": "http://github.com/aurelia/fetch-client"
},
"scripts": {
"test": "gulp test",
"ci": "gulp ci"
},
"jspm": {
"registry": "npm",
"jspmPackage": true,
"main": "aurelia-fetch-client",
"format": "amd",
"directories": {
"dist": "dist/amd"
},
"devDependencies": {
"aurelia-polyfills": "^1.0.0-beta.2.0.0"
}
},
"devDependencies": {
"aurelia-tools": "^0.2.4",
"babel-dts-generator": "^0.6.1",
"babel-eslint": "^6.1.2",
"babel-plugin-syntax-flow": "^6.8.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es2015-modules-amd": "^6.8.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.11.5",
"babel-plugin-transform-es2015-modules-systemjs": "^6.11.6",
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-plugin-transform-function-bind": "^6.8.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-es2015-loose": "^7.0.0",
"babel-preset-es2015-loose-native-modules": "^1.0.0",
"babel-preset-stage-1": "^6.5.0",
"del": "^2.2.1",
"eslint": "^3.1.1",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-bump": "^2.2.0",
"gulp-concat": "^2.6.0",
"gulp-conventional-changelog": "^1.1.0",
"gulp-eslint": "^3.0.1",
"gulp-ignore": "^2.0.1",
"gulp-insert": "^0.5.0",
"gulp-rename": "^1.2.2",
"gulp-typedoc": "^2.0.0",
"gulp-typedoc-extractor": "^0.0.8",
"gulp-typescript": "^2.13.6",
"gulp-util": "^3.0.7",
"jasmine-core": "^2.4.1",
"karma": "^1.1.2",
"karma-babel-preprocessor": "^6.0.1",
"karma-chrome-launcher": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-jasmine": "^1.0.2",
"karma-jspm": "^2.2.0",
"merge2": "^1.0.2",
"object.assign": "^4.0.4",
"require-dir": "^0.3.0",
"run-sequence": "^1.2.2",
"through2": "^2.0.1",
"typedoc": "^0.4.4",
"typescript": "^1.9.0-dev.20160622-1.0",
"vinyl": "^1.1.1",
"vinyl-paths": "^2.1.0",
"yargs": "^4.8.1"
},
"aurelia": {
"documentation": {
"articles": [
{
"title": "HTTP Services",
"href": "doc/article/en-US/http-services.md"
}
]
}
}
}
{
"name": "aurelia-fetch-client",
"version": "1.3.1",
"description": "A simple client based on the Fetch standard.",
"keywords": [
"aurelia",
"http",
"ajax",
"fetch"
],
"homepage": "http://aurelia.io",
"bugs": {
"url": "https://github.com/aurelia/fetch-client/issues"
},
"license": "MIT",
"author": "Rob Eisenberg <rob@bluespire.com> (http://robeisenberg.com/)",
"main": "dist/commonjs/aurelia-fetch-client.js",
"typings": "dist/aurelia-fetch-client.d.ts",
"repository": {
"type": "git",
"url": "http://github.com/aurelia/fetch-client"
},
"scripts": {
"test": "gulp test",
"ci": "gulp ci"
},
"jspm": {
"registry": "npm",
"main": "aurelia-fetch-client",
"format": "amd",
"directories": {
"dist": "dist/amd"
},
"dependencies": {
"aurelia-pal": "^1.3.0"
},
"devDependencies": {
"aurelia-pal-browser": "^1.0.0",
"aurelia-polyfills": "^1.0.0-beta.2.0.0"
}
},
"dependencies": {
"aurelia-pal": "^1.3.0"
},
"devDependencies": {
"aurelia-tools": "^0.2.4",
"babel-dts-generator": "^0.6.1",
"babel-eslint": "^6.1.2",
"babel-plugin-syntax-flow": "^6.8.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-es2015-modules-amd": "^6.8.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.11.5",
"babel-plugin-transform-es2015-modules-systemjs": "^6.11.6",
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-plugin-transform-function-bind": "^6.8.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-es2015-loose": "^7.0.0",
"babel-preset-es2015-loose-native-modules": "^1.0.0",
"babel-preset-stage-1": "^6.5.0",
"del": "^2.2.1",
"eslint": "^3.1.1",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-bump": "^2.2.0",
"gulp-concat": "^2.6.0",
"gulp-conventional-changelog": "^1.1.0",
"gulp-eslint": "^3.0.1",
"gulp-ignore": "^2.0.1",
"gulp-insert": "^0.5.0",
"gulp-rename": "^1.2.2",
"gulp-typedoc": "^2.0.0",
"gulp-typedoc-extractor": "^0.0.8",
"gulp-typescript": "^2.13.6",
"gulp-util": "^3.0.7",
"jasmine-core": "^2.4.1",
"karma": "^1.1.2",
"karma-babel-preprocessor": "^6.0.1",
"karma-chrome-launcher": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-jasmine": "^1.0.2",
"karma-jspm": "^2.2.0",
"merge2": "^1.0.2",
"object.assign": "^4.0.4",
"require-dir": "^0.3.0",
"run-sequence": "^1.2.2",
"through2": "^2.0.1",
"typedoc": "^0.4.4",
"typescript": "^1.9.0-dev.20160622-1.0",
"vinyl": "^1.1.1",
"vinyl-paths": "^2.1.0",
"yargs": "^4.8.1"
},
"aurelia": {
"documentation": {
"articles": [
{
"title": "HTTP Services",
"href": "doc/article/en-US/http-services.md"
}
]
}
}
}
7 changes: 7 additions & 0 deletions src/http-client-configuration.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {RequestInit, Interceptor} from './interfaces';
import {RetryInterceptor} from './retry-interceptor';

/**
* A class for configuring HttpClients.
Expand Down Expand Up @@ -87,6 +88,12 @@ export class HttpClientConfiguration {
rejectErrorResponses(): HttpClientConfiguration {
return this.withInterceptor({ response: rejectOnError });
}

withRetry( config?: RetryConfiguration) {
const interceptor : Interceptor = new RetryInterceptor(config);

return this.withInterceptor(interceptor);
}
}

function rejectOnError(response) {
Expand Down
16 changes: 16 additions & 0 deletions src/http-client.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {HttpClientConfiguration} from './http-client-configuration';
import {RequestInit, Interceptor} from './interfaces';
import {RetryInterceptor} from './retry-interceptor';

/**
* An HTTP client based on the Fetch API.
Expand Down Expand Up @@ -79,6 +80,21 @@ export class HttpClient {
throw new Error('Default headers must be a plain object.');
}

let interceptors = normalizedConfig.interceptors;

if (interceptors && interceptors.length ) {
// find if there is a RetryInterceptor
if (interceptors.filter( x => RetryInterceptor.prototype.isPrototypeOf(x)).length > 1) {
throw new Error('Only one RetryInterceptor is allowed.');
}

const retryInterceptorIndex = interceptors.findIndex( x => RetryInterceptor.prototype.isPrototypeOf(x));

if (retryInterceptorIndex >= 0 && retryInterceptorIndex !== interceptors.length - 1) {
throw new Error('The retry interceptor must be the last interceptor defined.');
}
}

this.baseUrl = normalizedConfig.baseUrl;
this.defaults = defaults;
this.interceptors = normalizedConfig.interceptors || [];
Expand Down
12 changes: 11 additions & 1 deletion src/interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ interface Interceptor {
* previous interceptor.
* @returns The response; or a Promise for one.
*/
responseError?: (error: any, request?: Request) => Response|Promise<Response>;
responseError?: (error: any, request?: Request, httpClient? : HttpClient) => Response|Promise<Response>;
}

/**
Expand Down Expand Up @@ -101,3 +101,13 @@ interface RequestInit {
*/
signal?: AbortSignal;
}

interface RetryConfiguration {
maxRetries: number;
interval?: number;
strategy?: number|(retryCount: number) => number;
minRandomInterval?: number;
maxRandomInterval?: number;
doRetry?: (response: Response, request: Request) => boolean | Promise<boolean>;
beforeRetry?: (request: Request, client: HttpClient) => Request | Promise<Request>;
}
Loading

0 comments on commit d16447a

Please sign in to comment.